[英]Relationship between Functor, Applicative Functor, and Monad
在阅读类型类时,我发现函子,应用函子和Monads之间的关系是严格提高能力的。 函子是可以映射的类型。 应用函子可以执行相同的操作并具有一定的效果。 单声道的效果可能不受限制 。 此外:
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 ,对monad的另一种定义可能是:
class Applicative m => Monad' m where
(>>=) :: m a -> (a -> m b) -> m b
这显然更简单, 并且可以巩固Functor <Applicative Functor <Monad。 那么,为什么不定义呢? 我知道应用函子是新功能,但是根据2010年Haskell报告第80页,这没有改变。 为什么是这样?
每个人都希望看到Applicative成为Monad的超类,但它会破坏太多的代码(如果消除了return
,则每个Monad实例都将变为无效),因此每个人都希望推迟,直到我们以避免破坏的方式扩展语言为止代码( 请参阅此处获取一项重要建议)。
Haskell 2010总体上是保守的,渐进式的改进,仅标准化了一些无争议的扩展,并打破了一个领域的兼容性,以使该标准与所有现有实现保持一致。 确实,Haskell 2010的库甚至不包含Applicative-人们对标准库的期望是标准化的,比您期望的要少。
希望我们会很快看到这种情况有所改善,但值得庆幸的是,这通常只是轻微的不便(必须在通用代码中编写liftM
而不是fmap
等)。
此时更改Monad的定义,将使很多现有代码(定义Monad实例的任何代码段)变得值得。
只有在这种改变有很大的实际利益的情况下,打破这种向后兼容的做法才是值得的。 在这种情况下,收益不是那么大(无论如何基本上都是理论上的收益),并且也不能证明这种破损是合理的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.