gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 05:13:31 32 4
gpt4 key购买 nike

标准库 Haskell 类型类 MonadPlus , Alternative ,和Monoid每个都提供两种语义基本相同的方法:

  • 空值:mzero , empty ,或mempty .
  • 运算符(operator) a -> a -> a将类型类中的值连接在一起: mplus , <|> ,或mappend .

所有三个都指定了实例应遵守的这些法律:

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

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

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

所以,我的疑问是:为什么有这三个极其相似的类?除了不同的父类(super class)约束之外,它们之间还有什么真正的区别吗?

最佳答案

<强> MonadPlusMonoid服务于不同的目的。

一个Monoid通过 kind 的类型进行参数化 * .

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

因此它可以为几乎任何类型实例化,只要有一个明显的关联运算符并且有一个单位。

但是,MonadPlus不仅指定您具有幺半群结构,而且还指定该结构与 Monad 的方式相关。有效,并且该结构不关心 monad 中包含的值,这(部分)由 MonadPlus 的事实表明。接受类似的争论* -> * .

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

除了幺半群定律之外,我们还有两组潜在的定律可以应用于 MonadPlus 。可悲的是,社区对于它们应该是什么样子存在不同意见。

至少我们知道

mzero >>= k = mzero

但是还有另外两个相互竞争的扩展,即左(原文如此)分布定律

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

和左捕获法则

mplus (return a) b = return a

所以 MonadPlus 的任何实例应满足这些附加法律中的一项或两项。

那么 Alternative 呢? ?

Applicative是在 Monad 之后定义的,逻辑上属于 Monad 的父类(super class),但很大程度上是由于 Haskell 98 中设计师面临的不同压力,甚至 Functor不是 Monad 的父类(super class)直到2015年。现在我们终于有了Applicative作为 Monad 的父类(super class)在 GHC 中(如果尚未在语言标准中。)

实际上,AlternativeApplicative什么MonadPlusMonad .

对于这些我们会得到

empty <*> m = empty

类似于我们的 MonadPlus并且存在类似的分配和捕获属性,您至少应该满足其中之一。

不幸的是,甚至empty <*> m = empty法律的主张过于强烈。它不适用于 Backwards ,例如!

当我们查看 MonadPlus 时,空 >>= f = 空法则几乎是强加给我们的。空结构中不能有任何“a”来调用函数 f无论如何。

但是,自从 Applicative不是 Monad 的父类(super class)和Alternative不是 MonadPlus 的父类(super class),我们最终分别定义两个实例。

而且,即使ApplicativeMonad 的父类(super class),您最终需要 MonadPlus无论如何都要上课,因为即使我们确实遵守了

empty <*> m = empty

这还不足以证明这一点

empty >>= f = empty

因此声称某物是 MonadPlus比声称的更强大Alternative .

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

例如 MonadPlusAlternative对于 Maybe做显而易见的事情:

instance MonadPlus Maybe where
mzero = Nothing
mplus (Just a) _ = Just a
mplus _ mb = mb

但是Monoid实例将半群提升为 Monoid 。可悲的是,因为不存在 Semigroup当时在 Haskell 98 中,它通过要求 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

TL;DR MonadPlus是比 Alternative 更强的主张,这又是一个比 Monoid 更强的主张。 ,而 MonadPlusAlternative类型的实例应该是相关的,Monoid可能(有时是)完全不同的东西。

关于haskell - 类型类 MonadPlus、Alternative 和 Monoid 之间的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10167879/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com