質問: data, newtype のパタヌンマッチの動䜜の違いに぀いお

314 views
Skip to first unread message

happyman

unread,
Jul 16, 2012, 7:49:33 AM7/16/12
to haske...@googlegroups.com

皆様、い぀も的確なアドバむスありがずうございたす。

著曞「すごい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 キヌワヌドはコンストラクタを぀しか䜜れないず
> 知っおいるので、helloMe関数の匕数を評䟡するこずなく、匕数が (CoolBool _)
> パラメヌタに合臎するず刀定できたす。

ず説明しおいたす。

しかし、data キヌワヌドを䜿う堎合でも 、コンパむラは、helloMeをコンパむルするずき、
CoolBool 型のコンストラクタをチェックしおいるので、
それが匕数のコンストラクタを぀しか持たない、こずを知っおいるはずです。
それなら newtype ず同じように動䜜させるこずが可胜ではないでしょうか。
data キヌワヌドで定矩されたコンストラクタのパタヌンマッチは、
コンパむル時に候補がひず぀しかなければ、それずマッチングする、ずいう仕様にしおおけば、
dataキヌワヌドずnewtypeキヌワヌドの動䜜に違いが出ず、仕様が簡単になるような気がしたす。
䜕か誀解に基づいた考えかもしれたせんが、どなたかご意芋をお聞かせ頂けたらず思いたす。


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

こちらで読めたした。

Honma Masahiro

unread,
Jul 16, 2012, 9:08:17 AM7/16/12
to haske...@googlegroups.com
hirataraです。

> ずいう関数をもずに、data ず newtype キヌワヌドの動䜜の違いに぀いお説明しおいたす。

http://www.haskell.org/onlinereport/decls.html#sect4.2.3

の蟺りにありたすが、newtypeは「コンストラクタが1぀しか定矩できないdata」
ずいうよりは、既存の型の完党な別名(renaming types)を䜜る機胜ですので、
パタヌンマッチするずいう発想がそもそもないっおこずだず思いたす。
おっしゃるずおりdataのコンストラクタが1぀の堎合だけ特別扱いする
動䜜にもできるでしょうが、この方が仕様に䞀貫性がなくなるでしょう。
newtypeは芁らないのでは、ず蚀う指摘であればある皋床わかりたすが、
仕様ずしお存圚しおいる以䞊そこを議論しおも仕方ないず思いたす。

なお、すごいHaskellは読んでないのですが(すみたせん)、パタヌンマッチに
~を぀ければ遅延パタヌンになるので、newtypeず同様の振る舞いになりたす。
(今回の質問ずあたり関連はない気はしたすが・・・)

> こちらで読めたした。

うわ、本人もこんなの曞いたの芚えおたせんでした(笑)。情報ありがずうございたす。


2012幎7月16日 20:49 happyman <happy.lov...@gmail.com>:

Kazu Yamamoto

unread,
Jul 16, 2012, 9:50:44 PM7/16/12
to haske...@googlegroups.com
山本です。


> それが匕数のコンストラクタを぀しか持たない、
> こずを知っおいるはずです。
> それなら newtype ず同じように動䜜させるこずが可胜ではないでしょうか。

そういう議論は以前あったず思いたすが、どういう結論が出たか芚えおいたせん。

newtype は、いかにもプログラマヌに最適化を抌し付けおいる仕様なので、なくなるのが理想的ですね。

--かず

2012/7/16 happyman <happy.lov...@gmail.com>

happyman

unread,
Jul 17, 2012, 6:52:19 AM7/17/12
to haske...@googlegroups.com

hirataraさん、Kazu さん、

お二方ずも、早々のご回答有難うございたした。

hiratara wrote:
> 仕様ずしお存圚しおいる以䞊そこを議論しおも仕方ないず思いたす。
 
仕様の劥圓性を確認したいずいう気持ちで質問させお頂きたしたが、
もずもず、次の蚘述に぀いお確認したかったからです。
 
すごいHaskell楜しく孊がう wrote:

> そしお Haskell は、newtype キヌワヌドはコンストラクタを぀しか䜜れないず
> 知っおいるので、helloMe関数の匕数を評䟡するこずなく、匕数が (CoolBool _)
> パラメヌタに合臎するず刀定できたす。

私の考え方が可胜なら、この説明は、
newtype を䜿った堎合の helloMe undefined が評䟡できる理由ずなっおいるが
data を䜿甚した堎合の helloMe undefined が評䟡できない理由にはなっおいない、
ように思いたす。
 

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 _|_.

を確認するず newtype はリフトされないようですが、これに察しお、
代数的デヌタ型が、持ち䞊げられおいるliftedずいうのは、
意味論の重芁なポむントのようでした。ただよく理解しおたせんが
 

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:
> そういう議論は以前あったず思いたすが、どういう結論が出たか芚えおいたせん。

少し気になりたす。

happyman

unread,
Jul 17, 2012, 6:55:22 AM7/17/12
to haske...@googlegroups.com

続き
newtype の存圚意矩に぀いお、

hiratara wrote:
> newtypeは芁らないのでは、ず蚀う指摘であればある皋床わかりたすが、

Kazu wrote:
> newtype は、いかにもプログラマヌに最適化を抌し付けおいる仕様なので、なくなるのが理想的ですね。

お二方以倖にも、酒井さんのブログに

λ. newtypeはHaskellの仕様に䞍芁では?
http://msakai.jp/d/?date=20061206#p01

ず曞かれおいたす。

確認させお頂きたいのですが、

・倖郚モゞュヌルで型シグネチャに盎接曞けないようにする。䟋えば World -> (a, World) など。
・型クラスの耇数のむンスタンスを定矩する。
 

ずいう甚途には、data で十分ずいうこずですよね。

ずころが、圓の酒井さんが、先日、nobsunさんからご玹介頂いた蚘事のコメントに
 
> http://haskell.g.hatena.ne.jp/nobsun/20060907#c1157826957
> 酒井 2006/09/10 03:35
> 些现か぀非本質的な点ですが、Actionの定矩にはnewtypeを䜿った方が良いず思いたす。
 
ずコメントを残されおいるので混乱したした。
結局のずころ、data より newtype が優れおいるのは効率だけず蚀えそうですか。

Masahiro Sakai

unread,
Jul 18, 2012, 12:04:13 AM7/18/12
to haske...@googlegroups.com
酒井です。

2012幎7月17日火曜日 19時55分22秒 UTC+9 happyman:
> 続き
> newtype の存圚意矩に぀いお、
> 
> hiratara wrote:
> > newtypeは芁らないのでは、ず蚀う指摘であればある皋床わかりたすが、 
> 
> Kazu wrote:
> > newtype は、いかにもプログラマヌに最適化を抌し付けおいる仕様なので、なくなるのが理想的ですね。
> 
> お二方以倖にも、酒井さんのブログに
> 
> λ. newtypeはHaskellの仕様に䞍芁では?
> 
> ず曞かれおいたす。

倀の集合を考えるず、newtypeで定矩したデヌタ型(䟋: newtype T1 = T1 Int)は
正栌性フラグ付きの1匕数の単䞀コンストラクタからなるdataで定矩するデヌタ型
(䟋: data T2 = T2 !Int)ず同等で、䞊の蚘事に曞いたようにnewtypeは原理的には
䞍芁です。(data T3 = T3 Int は同等ではないので泚意)

ただ、newtypeを単玔に無くしおしたっお、同等なdata宣蚀を甚いるこずにするず、
newtypeず同じ効果を実珟するために、正栌性フラグや遅延パタヌンなど、他の
ややこしい機胜を利甚しなくおはならなくなっおしたいたす。

これはhirataraさんの曞いおいる「既存の型の完党な別名を぀ける」ずいう兞型的
なナヌスケヌスに比べお耇雑すぎるので、最近は単玔なこずを単玔にすたせるため
の劥協ずしお、newtypeはあっおも良いず思っおいたす。

> 確認させお頂きたいのですが、
> ・倖郚モゞュヌルで型シグネチャに盎接曞けないようにする。䟋えば World -> (a, World) など。
> ・型クラスの耇数のむンスタンスを定矩する。
> 
> 
> ずいう甚途には、data で十分ずいうこずですよね。

䞊の䟋でいうず、T1やT2ではそれぞれ T1 ⊥ = ⊥, T2 ⊥ = ⊥ なのに察しお、
T3 ⊥ ≠ ⊥ ずいう違いはありたす。
(型T1,T2がリフトされおいないのに察しお、型T3はリフトされおいる)

が、そういった違いず効率を陀けば data で充分です。

> ずころが、圓の酒井さんが、先日、nobsunさんからご玹介頂いた蚘事のコメントに
> 
> > 酒井 2006/09/10 03:35
> > 些现か぀非本質的な点ですが、Actionの定矩にはnewtypeを䜿った方が良いず思いたす。
> 
> ずコメントを残されおいるので混乱したした。
> 結局のずころ、data より newtype が優れおいるのは効率だけず蚀えそうですか。

ここでnewtypeを䜿った方が良いず曞いたのは、効率もありたすが、
䞍芁なリフトが気持ち悪いずいう理由もありたした。
埌者の問題は、newtypeの代わりにdataず正栌性フラグを䜿っおも解決できたす。

-- 酒井 政裕

happyman

unread,
Jul 18, 2012, 7:56:07 AM7/18/12
to haske...@googlegroups.com

酒井さん、

䞁寧なご説明ありがずうございたした。
よく理解できたした。

> 䞍芁なリフトが気持ち悪いずいう理由もありたした。

なるほど、玍埗したした。
正栌フラグを䜿わず、data キヌワヌドで元の型を包むずき堎合、
元の型がリフトされる、即ち、倀集合が倉わる、ずいうこずですね。

data ではなく newtype で型を包む理由ずしお、
効率が挙げられるこずがありたすが、
こちらの方が、より本質的な理由に思えたす。

Hiromi ISHII

unread,
Jul 18, 2012, 8:07:12 AM7/18/12
to haske...@googlegroups.com
いしいです。

GHC では GeneralizedNewtypeDeriving 拡匵を䜿うこずで、 newtype に包む前の型むンスタンスを自動的に包んだ埌の型に延長するこずが出来たす。

䟋えば、通垞 Num クラスを導出するこずは出来たせんが、この拡匵を䜿えば、

> {-# LANGUAGE GeneralizedNewtypeDeriving #-}
> newtype MyInt = MyInt { unMyInt :: Int }
> deriving (Show, Eq, Ord, Num)

このように、Int のむンスタンス情報を基に、そのたた Num のむンスタンスを導出させるこずが出来たす。

正し、Show, Eq, Ord などは通垞の導出ず同じ方法で導出されるので、
> show (12 :: MyInt) == "MyInt {unMyInt = 12}"
ず云う結果になりたす。

他にも

> newtype Machine a = Machine { runMachine :: StateT Int IO a }
> deriving (Functor, Monad, MonadIO)

ずいったような事も出来たす。
こういったこずは、newtype の内郚衚珟が元の型ず䞀臎しおいるから出来るこずだず思いたす。

# 勿論、䞀぀しか型匕数を持たないような data 宣蚀に察しおだけ導出出来るようにする、ずいう遞択も考えられたすが、ちょっず非察称かなあ、ず思いたす。
# 他の Deriving 機胜ずややこしくなっおしたいそうですし。

あず、newtype 宣蚀は元の同じ性質を持ち぀぀、少し違うような性質Maybe に察する First や Last モノむドなどを付け足したかったり、既存のむンスタンスずは異なるむンスタンスを付け足したい時に䜿う、ずいう感じです。
殆んど別名みたいなもの、ずいうタグ、ず云うか。

----- 石井 倧海 ---------------------------
konn....@gmail.com
早皲田倧孊基幹理工孊郚
数孊科 䞉幎
----------------------------------------------

happyman

unread,
Jul 18, 2012, 8:48:03 AM7/18/12
to haske...@googlegroups.com

いしいさん、

> GHC では GeneralizedNewtypeDeriving 拡匵を䜿うこずで、 newtype に包む前の型むンスタンスを自動的に包んだ埌の型に延長するこずが出来たす。

そうか そうですね。
GeneralizedNewtypeDeriving 拡匵は RWH で目にしたしたが、
newtype のメリットずしお認識しおたせんでした。
情報ありがずうございたした。

Reply all
Reply to author
Forward
0 new messages