从某种意义上说,它们非常相似,因为它们是双重的。构造函数可以被认为是数据类型的签名函子的代数,并且在同一个函子上构造模式的余代数。
为了更加明确,我们考虑一下[]
。它的签名函子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)
能否请您做你的问题更精确?我不确定你的目标是什么,两者是出于不同的目的,一个构造函数构造值,而模式被用来将价值分开(广义而言)。 –