【发布时间】:2011-12-09 13:37:56
【问题描述】:
我一直很喜欢以下关于 monad 相对于 functor 的能力的直观解释:monad 可以改变形状;函子不能。
例如:length $ fmap f [1,2,3] 始终等于 3。
但是,对于 monad,length $ [1,2,3] >>= g 通常不等于 3。例如,如果g 定义为:
g :: (Num a) => a -> [a]
g x = if x==2 then [] else [x]
那么[1,2,3] >>= g 等于[1,3]。
让我有点困扰的是g 的类型签名。用通用的单子类型定义一个改变输入形状的函数似乎是不可能的,例如:
h :: (Monad m, Num a) => a -> m a
MonadPlus 或 MonadZero 类型类具有相关的零元素,可以用来代替 [],但现在我们拥有的不仅仅是 monad。
我说的对吗?如果是这样,有没有办法向 Haskell 的新手表达这种微妙之处。我想让我心爱的“单子可以改变形状”这句话,更诚实一点;如果需要的话。
【问题讨论】: