- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
标准库 Haskell 类型类 MonadPlus
, Alternative
,和Monoid
每个都提供两种语义基本相同的方法:
mzero
, empty
,或mempty
.a -> a -> a
将类型类中的值连接在一起: mplus
, <|>
,或mappend
.所有三个都指定了实例应遵守的这些法律:
mempty `mappend` x = x
x `mappend` mempty = x
因此,这三个类型类似乎都提供相同方法。
( Alternative
还提供 some
和 many
,但它们的默认定义通常就足够了,因此对于这个问题来说它们并不是太重要。)
所以,我的疑问是:为什么有这三个极其相似的类?除了不同的父类(super class)约束之外,它们之间还有什么真正的区别吗?
最佳答案
<强> MonadPlus
和Monoid
服务于不同的目的。
一个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 中(如果尚未在语言标准中。)
实际上,Alternative
是Applicative
什么MonadPlus
是Monad
.
对于这些我们会得到
empty <*> m = empty
类似于我们的 MonadPlus
并且存在类似的分配和捕获属性,您至少应该满足其中之一。
不幸的是,甚至empty <*> m = empty
法律的主张过于强烈。它不适用于 Backwards ,例如!
当我们查看 MonadPlus 时,空 >>= f = 空法则几乎是强加给我们的。空结构中不能有任何“a”来调用函数 f
无论如何。
但是,自从 Applicative
不是 Monad
的父类(super class)和Alternative
不是 MonadPlus
的父类(super class),我们最终分别定义两个实例。
而且,即使Applicative
是 Monad
的父类(super class),您最终需要 MonadPlus
无论如何都要上课,因为即使我们确实遵守了
empty <*> m = empty
这还不足以证明这一点
empty >>= f = empty
因此声称某物是 MonadPlus
比声称的更强大Alternative
.
现在,按照惯例,MonadPlus
和Alternative
对于给定类型应该一致,但是 Monoid
可能完全不同。
例如 MonadPlus
和Alternative
对于 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
更强的主张。 ,而 MonadPlus
和Alternative
类型的实例应该是相关的,Monoid
可能(有时是)完全不同的东西。
关于haskell - 类型类 MonadPlus、Alternative 和 Monoid 之间的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10167879/
也许这些陈述都不是绝对精确的,但是单子(monad)通常被定义为“内仿函数类别中的一个幺半群”; Haskell Alternative 被定义为“应用仿函数上的幺半群”,其中 applicative
Applicative 是一个 Monoidal Functor : mappend :: f -> f -> f $ :: (a -> b) -> a ->
假设我有一个函数列表 E => Either[Exception, Unit] 在事件 E 上调用并累积错误以返回 Either[List [异常(exception)],单位]。 type Even
在 Scala 函数式编程一书中,我看到了以下签名: def productMonoid[A,B](A: Monoid[A], B: Monoid[B]): Monoid[(A,B)] 描述是这样说的
从下面的例子中,我认为说 String 在串联操作下定义了一个幺半群是正确的,因为它是一个关联二元操作,而 String 恰好有一个标识元素,它是一个空字符串 "" 。 scala> ("" + "J
Typeclassopedia提出以下练习: Implement pure and () in terms of unit and (**), and vice versa. 这是Monoidal和M
从下面的例子中,我认为说 String 在串联操作下定义了一个幺半群是正确的,因为它是一个关联二元操作,而 String 恰好有一个标识元素,它是一个空字符串 "" 。 scala> ("" + "J
我之前定义了一个函数,它接受一个列表 Maybe s 并将其变成 Maybe一个列表,像这样: floop :: [Maybe a] -> Maybe [a] floop [] = Just [] f
HLearn 的自述文件指出 Monoid 类型类用于并行批量训练。我在几个文件中看到了 trainMonoid ,但我很难剖析这个巨大的代码库。有人可以用初学者友好的术语解释它是如何工作的吗?我猜这
假设我有如下的 Monoid 特征: trait Monoid[A] { def combine(a1: A, a2: A): A def identity: A } 现在如果我想为此写一个
在 haskell IO 类型中有 Monoid 的实例: instance Monoid a => Monoid (IO a) where mempty = pure empty 如果我有三
trait Monoid[A] { def op(a1: A, a2: A): A def zero: A } def mapMergeMonoid[K, V](V: Monoid[V]):
我正在研究这个 Functional Programming in Scala练习: // But what if our list has an element type that doesn't
我试图以更实际的方式理解 monads 和 monoids 之间的关系。如果这个问题没有意义,我提前道歉,我仍在挣扎。 假设例如,我有: trait Monoid[T] { def zero: T
我想写一个方法mergeKeys将值分组在 Iterable[(K, V)] 中由 key 。例如,我可以写: def mergeKeysList[K, V](iter: Iterable[(K,
我正在阅读一本书,内容如下: sealed trait Currency case object USD extends Currency ... other currency types case
我在具有 SceneGraph 类型字段“_scene”的记录上使用下面的代码。我使用 makeLenses 为它创建了镜头。 inputGame :: Input -> Game -> Game i
我有一个数据类型是 Monoid 的实例所以我可以得到很好的值(value)观组合: data R a = R String (Maybe (String → a)) instance Monoid
根据定义或幺半群,二元运算符必须是关联的,例如A op (B op C) == (A op B) op C . base mconcat definition在 haskell 是: mconcat
这个问题在这里已经有了答案: Why MonadPlus and not Monad + Monoid? (4 个回答) 6年前关闭。 我对 Monads 和 Monoids 都很陌生,最近还了解了
我是一名优秀的程序员,十分优秀!