我对Monads
和Monoids
都是新手,最近也了解了MonadPlus
。在我看来,Monoid
和MonadPlus
都提供了具有关联二元操作和标识的类型。(用数学术语来说,我称之为半群。)那么Monoid
和MonadPlus
之间的区别是什么呢
发布于 2013-06-12 08:58:14
semigroup是配备有关联二元运算的结构。monoid是具有用于二元运算的单位元素的半群。
单子和半群
每个monad都必须遵守the monad laws。对于我们的例子,重要的是结合性定律。使用>>=
表示
(m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)
现在,让我们应用这个定律来推导>> :: m a -> m b -> m b
的结合性
(m >> n) >> p ≡ (m >>= \_ -> n) >>= \_ -> p
≡ m >>= (\x -> (\_ -> n) x >>= \_ -> p)
≡ m >>= (\x -> n >>= \_ -> p)
≡ m >>= (\x -> n >> p)
≡ m >> (n >> p)
(我们选择了x
,这样它就不会出现在m
、n
或p
中)。
如果我们对类型代码进行专门化(用b
代替a
),我们可以看到在<>e226m a -> m a -> m a > m a
**.**上,任何类型的a
形成了一个半群。由于对任何<代码>D30都是如此,我们得到了一个由<代码>D31索引的半群类。然而,它们通常不是么半群-我们没有>>
的身份元素。
MonadPlus和么半群
MonadPlus
又添加了两个操作:mplus
和mzero
。MonadPlus
laws明确声明,对于任意a
,mplus
和mzero
必须在m a
上形成一个么半群。再一次,我们得到一类由a
索引的么半群。
请注意MonadPlus
和Monoid
之间的区别:Monoid
说,对于所有可能的a
类型,m a
类型都满足偏置规则。这是一个更强的条件。
因此,一个MonadPlus
实例形成了两种不同的代数结构:一类是具有>>
的半群,另一类是具有mplus
和mzero
的么半群。(这并不少见,例如,大于零的自然数集与+
形成半群,与×
和1
形成么半群。)
发布于 2013-06-12 02:52:40
如果我们有MonadPlus m
成立,那么你会说m
是一个函数,但是m a
(将a
应用于类型“Monad
”m
得到的类型)是么半群。
如果我们定义(类似于Data.Monoid
的定义,但我们将在后面使用它)
class Semigroup a where (<>) :: a -> a -> a
class Semigroup a => Monoid a where zero :: a
然后它就有了
mzero :: MonadPlus m => m a
mplus :: MonadPlus m => m a -> m a -> m a
具有相当可比的类型和适当的法则
-- 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
{-# LANGUAGE FlexibleInstances #-}
instance MonadPlus m => Semigroup (m a) where (<>) = mplus
instance MonadPlus m => Monoid (m a) where zero = mzero
尽管它们与Data.Monoid
中的实例严重重叠,这可能是它不是标准实例的原因。
像这样的么半群的另一个例子是Control.Applicative
的Alternative m => m a
。
发布于 2014-11-14 10:24:40
我必须强调一个非常重要的区别:不像Monoid,也不像其他答案所说的那样,MonadPlus 提供了一个具有关联的二元操作和标识的类型。哈斯克尔报告是唯一可以声明标准状态的文件,它没有指定MonadPlus的定律,因此不要求mplus是结合性的,或者mzero是它的左或右单位。也许作者仍然在争论这些定律: mplus有很好的理由不能联想。例如,如果mplus是结合型但非交换型的,则MonadPlus表示的非确定性搜索计算无法完成(也就是说,存在我们找不到的解)。由于mplus很少是可交换的,如果我们坚持结合性,任何完整的非确定性搜索过程都不能用MonadPlus表示。关于SC:Must mplus always be associative上的MonadPlus法律问题已经有了详细的讨论
https://stackoverflow.com/questions/17056881
复制相似问题