标准库Haskell类型类MonadPlus
,Alternative
和Monoid
各自提供两种语义基本相同的方法:
mzero
,empty
或mempty
。a -> a -> a
:mplus
,<|>
或mappend
。所有三个都规定了应遵守的法律:
mempty `mappend` x = x
x `mappend` mempty = x
因此,似乎三个类型类都提供了相同的方法。
(Alternative
还提供some
和many
,但他们的默认定义通常已足够,因此就此问题而言,它们并不太重要。)
所以,我的疑问是:为什么这三个极为相似的类?除了不同的超类约束之外,它们之间是否有任何真正的区别?
答案 0 :(得分:108)
MonadPlus
和Monoid
有不同的用途。
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
的超类(如果还没有语言标准那样)。
有效地,Applicative
是Monad
Alternative
到Applicative
的内容。
对于这些我们得到
MonadPlus
类似于我们对Monad
所拥有的内容,并且存在类似的分配和捕获属性,至少其中一个属性应该满足。
不幸的是,即使empty <*> m = empty
法律也是如此强烈。例如,它并不适用于Backwards!
当我们查看MonadPlus时,空的&gt;&gt; = f =空法几乎被强加给我们。无论如何,空构造中都没有任何内容可以调用函数MonadPlus
。
但是,由于empty <*> m = empty
不,f
和Applicative
的超类不是 {{1}的超类我们最终分别定义了两个实例。
此外,即使Monad
是Alternative
的超类,您仍然需要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
可能(有时是)完全不同的东西。