当阅读类型类相关内容时,我发现函子、应用函子和单子之间的关系是严格递增的。函子是可以映射的类型。应用函子可以对某些影响进行相同的操作。单子可以对可能不受限制的影响进行相同的操作。此外:
根据 Brent Yorgey 的优秀 typeclassopedia,单子的另一种定义可能是:
Every Monad is an Applicative Functor
Every Applicative Functor is a Functor
应用函子的定义清楚地表明:
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
但是Monad的定义是:
class Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
(>>) :: m a -> m b -> m b
m >> n = m >>= \_ -> n
fail :: String -> m a
根据 Brent Yorgey 的优秀 typeclassopedia,单子的另一种定义可能是:
class Applicative m => Monad' m where
(>>=) :: m a -> (a -> m b) -> m b
显然更简单,而且会巩固Functor < Applicative Functor < Monad的定义。那么为什么不采用这个定义呢?我知道applicative functors是新的,但根据2010 Haskell Report第80页,这并没有改变。为什么呢?
(<*>) :: f (a -> b) -> f a -> f b
和(=<<) :: (a -> m b) -> m a -> m b
的类型,即结果中的m
部分可以依赖于输入的a
,而对于applicative,结果中的f
部分必须独立于a
输入的值相同。 - hammar