在阅读类型类时,我已经看到Functors,Applicative Functors和Monads之间的关系是严格增加的权力。函数是可以映射的类型。 Applicative Functors可以使用某些效果执行相同的操作。 Monads与可能不受限制的效果相同。此外:
Every Monad is an Applicative Functor
Every Applicative Functor is a Functor
Applicative 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,monad的替代定义可能是:
class Applicative m => Monad' m where
(>>=) :: m a -> (a -> m b) -> m b
这显然更简单和会巩固Functor&lt; Applicative Functor&lt;单子。那么为什么这不是定义呢?我知道applicative functor是新的,但根据2010 Haskell Report第80页,这没有改变。这是为什么?
答案 0 :(得分:27)
每个人都希望看到Applicative成为Monad的超类,但它会破坏如此多的代码(如果消除了return
,每个当前的Monad实例都变得无效),每个人都想要推迟,直到我们可以扩展语言以这种方式避免破坏代码(see here为一个突出的提案)。
Haskell 2010在一般情况下是一个保守的渐进式改进,仅标准化了一些无争议的扩展并打破了one area中的兼容性,使标准与每个现有实现一致。事实上,Haskell 2010的图书馆甚至不包括Applicative - 人们对the standard library所期望的内容的标准化程度低于您的预期。
希望我们很快就会看到情况有所改善,但幸运的是,这通常只是一个轻微的不便(必须在通用代码中写liftM
而不是fmap
等。)
答案 1 :(得分:8)
此时更改Monad的定义会破坏很多现有代码(定义Monad实例的任何代码段)是值得的。
如果对变更有很大的实际好处,那么向后突破这种兼容性是值得的。在这种情况下,利益并不是那么大(而且主要是理论上的)并且不能证明这一数量的破损。