首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Monoid vs MonadPlus

Monoid vs MonadPlus
EN

Stack Overflow用户
提问于 2013-06-12 10:40:07
回答 3查看 5.1K关注 0票数 24

我对MonadsMonoids都是新手,最近也了解了MonadPlus。在我看来,MonoidMonadPlus都提供了具有关联二元操作和标识的类型。(用数学术语来说,我称之为半群。)那么MonoidMonadPlus之间的区别是什么呢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-06-12 16:58:14

semigroup是配备有关联二元运算的结构。monoid是具有用于二元运算的单位元素的半群。

单子和半群

每个monad都必须遵守the monad laws。对于我们的例子,重要的是结合性定律。使用>>=表示

代码语言:javascript
运行
复制
(m >>= f) >>= g     ≡   m >>= (\x -> f x >>= g)

现在,让我们应用这个定律来推导>> :: m a -> m b -> m b的结合性

代码语言:javascript
运行
复制
(m >> n) >> p       ≡ (m >>= \_ -> n) >>= \_ -> p
                    ≡ m >>= (\x -> (\_ -> n) x >>= \_ -> p)
                    ≡ m >>= (\x -> n >>= \_ -> p)
                    ≡ m >>= (\x -> n >> p)
                    ≡ m >> (n >> p)

(我们选择了x,这样它就不会出现在mnp中)。

如果我们对类型代码进行专门化(用b代替a),我们可以看到在<>e226m a -> m a -> m a > m a**.**上,任何类型的a形成了一个半群。由于对任何<代码>D30都是如此,我们得到了一个由<代码>D31索引的半群类。然而,它们通常不是么半群-我们没有>>的身份元素。

MonadPlus和么半群

MonadPlus又添加了两个操作:mplusmzeroMonadPlus laws明确声明,对于任意amplusmzero必须在m a上形成一个么半群。再一次,我们得到一类由a索引的么半群。

请注意MonadPlusMonoid之间的区别:Monoid说,对于所有可能的a类型,m a类型都满足偏置规则。这是一个更强的条件。

因此,一个MonadPlus实例形成了两种不同的代数结构:一类是具有>>的半群,另一类是具有mplusmzero的么半群。(这并不少见,例如,大于零的自然数集与+形成半群,与×1形成么半群。)

票数 34
EN

Stack Overflow用户

发布于 2013-06-12 10:52:40

如果我们有MonadPlus m成立,那么你会说m是一个函数,但是m a (将a应用于类型“Monadm得到的类型)是么半群。

如果我们定义(类似于Data.Monoid的定义,但我们将在后面使用它)

代码语言:javascript
运行
复制
class                Semigroup a where  (<>) :: a -> a -> a
class Semigroup a => Monoid    a where  zero :: a

然后它就有了

代码语言:javascript
运行
复制
mzero :: MonadPlus m => m a
mplus :: MonadPlus m => m a -> m a -> m a

具有相当可比的类型和适当的法则

代码语言:javascript
运行
复制
-- left and right identity
mplus a     mzero   ==   a
mplus mzero a       ==   a

-- associativity
(a `mplus` b) `mplus` c   ==   a `mplus` (b `mplus` c)

如果我们使用-XFlexibleInstances,我们甚至可以定义一个Haskell Monoid

代码语言:javascript
运行
复制
{-# LANGUAGE FlexibleInstances #-}
instance MonadPlus m => Semigroup (m a) where  (<>) = mplus
instance MonadPlus m => Monoid    (m a) where  zero = mzero

尽管它们与Data.Monoid中的实例严重重叠,这可能是它不是标准实例的原因。

像这样的么半群的另一个例子是Control.ApplicativeAlternative m => m a

票数 12
EN

Stack Overflow用户

发布于 2014-11-14 18:24:40

我必须强调一个非常重要的区别:不像Monoid,也不像其他答案所说的那样,MonadPlus 提供了一个具有关联的二元操作和标识的类型。哈斯克尔报告是唯一可以声明标准状态的文件,它没有指定MonadPlus的定律,因此不要求mplus是结合性的,或者mzero是它的左或右单位。也许作者仍然在争论这些定律: mplus有很好的理由不能联想。例如,如果mplus是结合型但非交换型的,则MonadPlus表示的非确定性搜索计算无法完成(也就是说,存在我们找不到的解)。由于mplus很少是可交换的,如果我们坚持结合性,任何完整的非确定性搜索过程都不能用MonadPlus表示。关于SC:Must mplus always be associative上的MonadPlus法律问题已经有了详细的讨论

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

https://stackoverflow.com/questions/17056881

复制
相关文章

相似问题

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