從某種意義上說,它們非常相似,因爲它們是雙重的。構造函數可以被認爲是數據類型的簽名函子的代數,並且在同一個函子上構造模式的餘代數。
爲了更加明確,我們考慮一下[]
。它的簽名函子T_A X = 1 + A * X
或者,在Haskell
type ListF a x = Maybe (a, x)
具有明顯的Functor
實例。我們可以看到,ListF
- 代數與List
載體都只是它的構造
-- general definition
type Algebra f a = f a -> a
consList :: Algebra (ListF a) [a]
consList Nothing = []
consList (Just (a, as)) = a:as
雙重,我們可以看看ListF
的餘代數與List
爲載體
type Coalgebra f a = a -> f a
unconsList :: Coalgebra (ListF a) [a]
unconsList [] = Nothing
unconsList (a:as) = Just (a, as)
,並進一步看到安全版本head
和tail
是非常自然的破壞者[]
headMay :: [a] -> Maybe a
headMay = fmap fst . unconsList
tailMay :: [a] -> Maybe a
tailMay = fmap snd . unconsList
這促成了一個私人寵物peeve約head
和tail
甚至不是特別好的功能,忽視他們的偏好---他們只是在無限名單上有自己的簽名函子T A X = A*X
。
現在在Haskell函子的initial Algebra
and final Coalgebra
一致爲仿
newtype Fix f = Fix { unfix :: f (Fix f) }
這是什麼樣的數據類型的定點。我們可以證明[a]
同構Fix (ListF a)
fwd :: [a] -> Fix (ListF a)
fwd [] = Fix Nothing
fwd (a:as) = Fix (Just (a, fwd as))
bwd :: Fix (ListF a) -> [a]
bwd (Fix Nothing) = []
bwd (Fix (Just (a, fixed))) = a : bwd fixed
這對使用的數據類型本身作爲兩個構造和模式提供了理由,但如果你創建其他種類的「餘代數樣」的東西,那麼你可以有一線例如由She或pattern combinators提供的類模式。
有關的圖案和構造的二元性有了更深的瞭解,請嘗試使用數據類型上面再次做這個練習像
data Tree a = Leaf | Branch (Tree a) a (Tree a)
其簽名函子T A X = 1 + X*A*X
或
type TreeF a x = Maybe (x,a,x)
能否請您做你的問題更精確?我不確定你的目標是什麼,兩者是出於不同的目的,一個構造函數構造值,而模式被用來將價值分開(廣義而言)。 –