类型MonadPlus,Alternative和Monoid之间的区别?

时间:2012-04-16 01:53:55

标签: haskell functional-programming typeclass applicative monoids

标准库Haskell类型类MonadPlusAlternativeMonoid各自提供两种语义基本相同的方法:

  • 空值:mzeroemptymempty
  • 将类型类中的值连接在一起的运算符a -> a -> amplus<|>mappend

所有三个都规定了应遵守的法律:

mempty `mappend` x = x
x `mappend` mempty = x

因此,似乎三个类型类都提供了相同的方法。

Alternative还提供somemany,但他们的默认定义通常已足够,因此就此问题而言,它们并不太重要。)

所以,我的疑问是:为什么这三个极为相似的类?除了不同的超类约束之外,它们之间是否有任何真正的区别?

1 个答案:

答案 0 :(得分:108)

MonadPlusMonoid有不同的用途。

Monoid是针对某种类型*进行参数化的。

class Monoid m where
    mempty :: m
    mappend :: m -> m -> m

所以它可以被几乎任何类型实例化,其中有一个明显的运算符是关联的并且有一个单位。

但是,MonadPlus不仅指定您具有幺半群结构,而且还指出该结构与Monad如何工作,相关,该结构不具有&# 39;关心monad中包含的值,这是(部分)由MonadPlus采用种类* -> *的论证表示。

class Monad m => MonadPlus m where
    mzero :: m a
    mplus :: m a -> m a -> m a

除了幺半群法律,我们还有两套可能适用于MonadPlus的法律。可悲的是,社区不同意他们应该是什么。

至少我们知道

mzero >>= k = mzero

但还有另外两个竞争扩展,左(sic)分配法

mplus a b >>= k = mplus (a >>= k) (b >>= k)

和左捕法律

mplus (return a) b = return a

因此MonadPlus的任何实例都应满足其中一项或两项附加法律。

那么Alternative呢?

Applicative是在Monad之后定义的,并且在逻辑上属于Monad的超类,但主要是由于Haskell 98中设计师的压力不同,甚至{{1} } {@ 1}}的超级类直到2015年。现在我们终于将Functor作为GHC中Monad的超类(如果还没有语言标准那样)。

有效地,ApplicativeMonad AlternativeApplicative的内容。

对于这些我们得到

MonadPlus

类似于我们对Monad所拥有的内容,并且存在类似的分配和捕获属性,至少其中一个属性应该满足。

不幸的是,即使empty <*> m = empty 法律也是如此强烈。例如,它并不适用于Backwards

当我们查看MonadPlus时,空的&gt;&gt; = f =空法几乎被强加给我们。无论如何,空构造中都没有任何内容可以调用函数MonadPlus

但是,由于empty <*> m = empty fApplicative的超类不是 {{1}的超类我们最终分别定义了两个实例。

此外,即使MonadAlternative的超类,您仍然需要MonadPlus课程,因为即使我们遵守了

Applicative

并不足以证明

Monad

声称某事物是MonadPlus比宣称empty <*> m = empty 更强。

现在,按照惯例,给定类型的empty >>= f = empty MonadPlus应该一致,但Alternative可能完全不同。

例如,MonadPlus的{​​{1}}和Alternative做了显而易见的事情:

Monoid

但是MonadPlus实例将半群提升为Alternative。遗憾的是,因为当时在Haskell 98中没有Maybe类,它通过请求instance MonadPlus Maybe where mzero = Nothing mplus (Just a) _ = Just a mplus _ mb = mb 但不使用其单位来实现。 ಠ_ಠ

Monoid

TL; DR Monoid是一个比Semigroup更强的声明,而Monoid的声明要强于instance Monoid a => Monoid (Maybe a) where mempty = Nothing mappend (Just a) (Just b) = Just (mappend a b) mappend Nothing x = x mappend x Nothing = x mappend Nothing Nothing = Nothing ,而MonadPlus则更强。和Alternative类型的实例应该相关,Monoid可能(有时是)完全不同的东西。