在“点菜数据类型”中,Swierstra 写道,给定Free
(他称之为Term
),Zero
您可以实现 Identity monad:
data Term f a = Pure a
| Impure (f (Term f a))
data Zero a
Term Zero
现在是 Identity monad。我明白为什么会这样。问题是由于讨厌的约束,我永远不能Term Zero
用作 Monad :Functor f =>
instance Functor f => Monad (Term f) where
return x = Pure x
(Pure x) >>= f = f x
(Impure f) >>= t = Impure (fmap (>>=f) t)
如何制作Zero
仿函数?
instance Functor Zero where
fmap f z = ???
这里似乎有一个技巧:因为Zero
没有构造函数,Impure
所以永远不能使用,所以永远不会调用Impure
case 。>>=
这意味着fmap
永远不会被调用,所以在某种意义上这是可以的:
instance Functor Zero where
fmap f z = undefined
问题是,这感觉像是作弊。我错过了什么?Zero
实际上是一个函子吗?或者可能Zero
不是 Functor,这是我们Free
在 Haskell 中表达方式的一个缺点?