Hutton本2に「newtypeで宣言するデータ型も再帰的にできる」って書いてあるんですが、これは誤りですよね? 再帰的にできるのは、data だけですよね?
newtype NewTypeRecursion a = N (Either (NewTypeRecursion a) a)newtype Void = Void Void みたいなのも使いましたよ.type は型の計算が遅延しませんが, newtype は遅延するのが強みだと思っていました(再帰型の場合は type は無限再帰が起き停止しなくなりますが, newtype は型上は data と同じ扱いなので新しい型が作られるだけですね)Void は「値を構成できない型」を作るためで,“矛盾“に相当します.定理証明をするためですね.newtype で再帰型は割と使う人なのですが, Cofree とかはnewtype Cofree f a = Cofree (a, f (Cofree f a))
data を使うべきというのはそうですが)type と newtype , data の大きな違いはtype は再帰型が書けないが, newtype / data は書ける (type はインスタンスにできないが, newtype / data はインスタンスにできるnewtype はコンストラクタが実行時に無いように振舞うnewtype で再帰ができると書いてしまうと、例を出すべきですが、例が初心者のレベルを超えていると思います。newtype は再帰できるという説明は見つけられませんでした。newtype が再帰できる」とは書かない方がいいと思います。H本をぱらっと読み返してみましたが、 newtype は再帰できるという説明は見つけられませんでした。すいません,確かに書いてないようですね.これは僕の勘違いでした.newtype Tree = Tree (Int, [Tree])
Fix を出す必要はないんじゃないかと(これは, Hutton本1だと type declaration で書けない例として紹介されていますね)Tree の例は素敵ですね。訳注にこれを書くのが補完し合っていていいかも。newtype は、初版にはなく、第2版から入りました。print $ (unsafeCoerce True :: Int) を実行してみたら 2305843009213693952 と表示されました。64bit に変換すると 0010000000000000000000000000000000000000000000000000000000000000 になり、GHCの内部表現と関係していそうなんですけど、どうしてこうなるんですか?ghci> import Unsafe.Coerce ghci> print $ (unsafeCoerce (-1::Int) :: Word) 18446744073709551615
print (unsafeCoerce True :: IntOrBool) が SEGV になったのは, 5764607523051092410 をBool値のヒープを指し示すポインタだと思って飛ぼうとしたせいだと思いますね.Bool値のコンストラクタはフィールドを特に持たないので,フィールドじゃない領域をフィールドだと思って参照した結果,そういう結果が返ってくるんだと思います(主に True だと True_closure + 9 , False だと False_closure + 8 を I64 表現だと解釈した結果こういう表示になってるようです.毎回実行するごとに結果が変わっていたので,多分空いてるヒープ領域なんだと思います)ghci> main -4035224716524808016
$ runghc Unsafe.hs -4035224717148402896 $ runghc Unsafe.hs -4035224717726351680
+--------+--------+--------+ |info ptr|payload1|payload2|.. +--------+--------+--------+
Bool型のTrueコンストラクタの場合 info ptr +--------+ | Trueへ | (ここは無し) +--------+ Int型の数値の場合 info ptr payload1 +--------+--------+ | I#へ | Int値 | +--------+--------+