皆様、いつも的確なアドバイスありがとうございます。
著書「すごいHaskell楽しく学ぼう!」を読んでいて、
また、些細な点が気になりましたので、質問させて頂きます。
P.262(12.1 既存の型を新しい型にくるむ)では、
helloMe :: CoolBool -> String
helloMe (CoolBool _) = "hello"
という関数をもとに、data と newtype キーワードの動作の違いについて説明しています。
■ dataキーワードで CoolBool 型を定義した場合
data CoolBool = CoolBool { getCoolBool :: Bool }
<実行結果>
ghci> helloMe undefined
"*** Exception: Prelude.undefined
■ newtypeキーワードで CoolBool 型を定義した場合
newtype CoolBool = CoolBool { getCoolBool :: Bool }
<実行結果>
*Main> helloMe undefined
"hello"
この違いについては、
> そして Haskell は、newtype キーワードはコンストラクタを1つしか作れないと
> 知っているので、helloMe関数の引数を評価することなく、引数が (CoolBool _)
> パラメータに合致すると判定できます。
と説明しています。
hiratara さん、
> http://d.hatena.ne.jp/hirataraSideB/20090606/p1
> dataとnewtypeのちがいのわかりやすい例が消えている。本当に困っている。
dataとnewtypeのちがいのわかりやすい例
http://web.archive.org/web/20070122231856/http://haskell.g.hatena.ne.jp/jmk/20061203
こちらで読めました。
hirataraさん、Kazu さん、
お二方とも、早々のご回答有難うございました。
> そして Haskell は、newtype キーワードはコンストラクタを1つしか作れないと
> 知っているので、helloMe関数の引数を評価することなく、引数が (CoolBool _)
> パラメータに合致すると判定できます。
hiratara wrote:
> おっしゃるとおりdataのコンストラクタが1つの場合だけ特別扱いする
> 動作にもできるでしょうが、
と回答頂いたお陰で、この辺のモヤモヤは晴れました。
なお、
> http://www.haskell.org/onlinereport/decls.html#sect4.2.3
> 日本語 http://www.sampou.org/haskell/report-revised-j/decls.html#sect4.2.3
> 4.2.3 Datatype Renamings
> ...
> Unlike algebraic datatypes, the newtype constructor N is unlifted, so that N _|_ is the same as _|_.
Haskell/Denotational semantics ボトムと部分関数 ⊥ ボトム(Bottom)
http://ja.wikibooks.org/wiki/Haskell/Denotational_semantics#.E3.83.9C.E3.83.88.E3.83.A0.E3.81.A8.E9.83.A8.E5.88.86.E9.96.A2.E6.95.B0
Kazu wrote:
> そういう議論は以前あったと思いますが、どういう結論が出たか覚えていません。
少し気になります。
(続き)
newtype の存在意義について、
hiratara wrote:
> newtypeは要らないのでは、と言う指摘であればある程度わかりますが、
Kazu wrote:
> newtype は、いかにもプログラマーに最適化を押し付けている仕様なので、なくなるのが理想的ですね。
お二方以外にも、酒井さんのブログに
λ. newtypeはHaskellの仕様に不要では?
http://msakai.jp/d/?date=20061206#p01
と書かれています。
確認させて頂きたいのですが、
という用途には、data で十分ということですよね。
酒井さん、
丁寧なご説明ありがとうございました。
よく理解できました。
> 不要なリフトが気持ち悪いという理由もありました。
なるほど、納得しました。
正格フラグを使わず、data キーワードで元の型を包むとき場合、
元の型がリフトされる、即ち、値集合が変わる、ということですね。
data ではなく newtype で型を包む理由として、
効率が挙げられることがありますが、
こちらの方が、より本質的な理由に思えます。
いしいさん、
> GHC では GeneralizedNewtypeDeriving 拡張を使うことで、 newtype に包む前の型インスタンスを自動的に包んだ後の型に延長することが出来ます。
そうか! そうですね。
GeneralizedNewtypeDeriving 拡張は RWH で目にしましたが、
newtype のメリットとして認識してませんでした。
情報ありがとうございました。