繁体   English   中英

函子,应用函子和Monad之间的关系

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM