所有的ADT是同構的(幾乎 - 見端)的(,)
,Either
,()
,(->)
,Void
和Mu
一些組合,其中
data Void --using empty data decls or
newtype Void = Void Void
和Mu
計算函子的不動點
newtype Mu f = Mu (f (Mu f))
例如
data [a] = [] | (a:[a])
相同
data [a] = Mu (ListF a)
data ListF a f = End | Pair a f
其本身是同構的
newtype ListF a f = ListF (Either() (a,f))
因爲
data Maybe a = Nothing | Just a
同構
newtype Maybe a = Maybe (Either() a)
你有
newtype ListF a f = ListF (Maybe (a,f))
可在萬畝內聯到
data List a = List (Maybe (a,List a))
和你的定義
data List a = List a (Maybe (List a))
只是在穆的展開和消除外部的可能(對應於非空列表)
你就完成了......
幾件事情
使用自定義的ADT增加清晰度和類型安全
這普遍性有用:看GHC.Generic
好吧,我說幾乎是同構的。它不完全是,即
hmm = List (Just undefined)
在列表的[a] = [] | (a:[a])
定義中沒有等價值。這是因爲Haskell數據類型是coinductive,並且已被a point of criticism of the lazy evaluation model。你可以只用嚴格的資金和產品得到解決這些問題(和值函數調用),並加入一個特殊的「懶惰」的數據構造
data SPair a b = SPair !a !b
data SEither a b = SLeft !a | SRight !b
data Lazy a = Lazy a --Note, this has no obvious encoding in Pure CBV languages,
--although Laza a = (() -> a) is semantically correct,
--it is strictly less efficient than Haskell's CB-Need
,然後所有的同構可以忠實地編碼。
'Sup dawg我聽說你喜歡Monads,所以我把Monad放進你的Monad ...! 你見過'Maybe String'它實際上是類型'Maybe [Char]',但我認爲你正在重塑Monad變形金剛(參見http://en.wikibooks.org/wiki/Haskell/Monad_transformers),但我是不知道,因爲我自己現在不太熟悉單子。 – epsilonhalbe 2012-07-06 15:50:39
哦,我看到很多'Maybe String'(http://www.haskell.org/hoogle/?hoogle=Maybe+%5BChar%5D)[here],但它們有不同的含義。我只是指出''''是一種'Nothing'和東西,所以我想用'Nothing'去除「重新定義」。 – L01man 2012-07-06 15:59:29
這不是重新定義。用作monad時,List和Maybe可能有不同的語義。模糊線條和扔掉語法糖(特別是列表模式)是愚蠢的。 – 2012-07-06 16:01:13