首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类型MonadPlus、Alternative和Monoid之间的区别?

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

Stack Overflow用户
提问于 2012-04-16 01:53:55
回答 1查看 7.2K关注 0票数 91

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

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

这三项法律都具体规定了实例应遵守的这些法律:

代码语言:javascript
复制
mempty `mappend` x = x
x `mappend` mempty = x

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

(Alternative还提供了somemany,但是它们的默认定义通常是足够的,因此它们在这个问题上并不太重要。)

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-04-16 02:36:32

MonadPlus Monoid 的用途不同。

Monoid是在一种类型的*上参数化的。

代码语言:javascript
复制
class Monoid m where
    mempty :: m
    mappend :: m -> m -> m

因此,它可以被实例化,几乎任何类型,其中有一个明显的算子,是结合的,并有一个单位。

但是,MonadPlus不仅指定您有一个单面结构,而且该结构还与Monad的工作方式有关,而且该结构并不关心monad中包含的值,这(部分)是由MonadPlus接受一个类似的* -> *这一事实所指示的。

代码语言:javascript
复制
class Monad m => MonadPlus m where
    mzero :: m a
    mplus :: m a -> m a -> m a

除了一元律外,我们还有两组潜在的定律可以应用于MonadPlus。可悲的是,社会对他们应该成为什么样的人持不同意见。

至少我们知道

代码语言:javascript
复制
mzero >>= k = mzero

但是还有另外两个相互竞争的扩展,即左(sic)分布律。

代码语言:javascript
复制
mplus a b >>= k = mplus (a >>= k) (b >>= k)

左边的渔获法

代码语言:javascript
复制
mplus (return a) b = return a

因此,MonadPlus的任何实例都应该满足这两个附加定律中的一个或两个。

Alternative**?**:,那么呢?

Applicative是在Monad之后定义的,在逻辑上属于Monad的一个超类,但在很大程度上是由于Haskell 98的设计者所承受的压力不同,直到2015年Functor也不是Monad的超类。现在,我们终于在GHC中将Applicative作为Monad的超类(如果还没有在语言标准中)。

实际上,Alternative对于Applicative来说就像MonadPlus对于Monad一样。

为了这些我们会得到

代码语言:javascript
复制
empty <*> m = empty

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

不幸的是,即使是empty <*> m = empty法也过于有力。例如,它不适用于倒着

当我们看MonadPlus时,空>>= f=空律几乎是强加在我们身上的。空结构中不能有任何‘a’来调用函数f

但是,由于Applicative不是Monad的超类,Alternative也不是MonadPlus的超类,所以我们最终分别定义了两个实例。

此外,即使ApplicativeMonad的超类,您最终还是需要MonadPlus类,因为即使我们遵守了

代码语言:javascript
复制
empty <*> m = empty

严格来说,这还不足以证明

代码语言:javascript
复制
empty >>= f = empty

因此,声称某物是MonadPlus比声称它是Alternative更强大。

现在,按照惯例,对于给定类型的MonadPlusAlternative应该是一致的,但是Monoid可能完全不同。

例如,MonadPlusAlternative For Maybe做了显而易见的事情:

代码语言:javascript
复制
instance MonadPlus Maybe where
    mzero = Nothing
    mplus (Just a) _  = Just a
    mplus _        mb = mb

但是Monoid实例将一个半群提升为一个Monoid。可悲的是,因为在Haskell 98中当时还没有一个Semigroup类,所以它需要一个Monoid,而不是使用它的单元。ಠ_ಠ

代码语言:javascript
复制
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

TL; MonadPlus博士是一个比Alternative更强的主张,这反过来又是一个比Monoid更强的主张,虽然一种类型的MonadPlusAlternative实例应该是相关的,但Monoid可能是(有时也是)完全不同的东西。

票数 125
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10167879

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档