Monoid与MonadPlus

时间:2013-06-12 02:40:07

标签: haskell monads typeclass monoids

我对MonadsMonoids都很陌生,最近还了解了MonadPlus。从我看到,MonoidMonadPlus都提供了一个带有关联二进制操作和标识的类型。 (我用数学术语称这是一个半群。)那么MonoidMonadPlus之间有什么区别?

3 个答案:

答案 0 :(得分:31)

semigroup是配备有关联二进制运算的结构。 monoid是半群,具有二进制操作的标识元素。

Monads和semigroups

每个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,因此它不会出现在mnp中。

如果我们将>>专门化为m a -> m a -> m a类型(用b代替a),我们会看到适用于任何类型a的操作>>m a上形成半群。由于任何a都是如此,我们得到一个由a索引的半群。但是,它们通常不是幺半群 - 我们没有>>的身份元素。

MonadPlus和monoids

MonadPlus又添加了两项操作mplusmzeroMonadPlus laws明确声明mplusmzero必须在m a上为任意a形成一个幺半群。同样,我们得到了一类由a索引的幺半群。

请注意MonadPlusMonoid之间的区别:Monoid表示某些单一类型符合幺半群规则,而MonadPlus表示所有可能的a类型m a满足幺半群定律。这是一个更强大的条件。

因此,MonadPlus实例形成两种不同的代数结构:一类具有>>的半群和一类具有mplusmzero的幺半群。 (这不是一种不常见的事情,例如,大于零的自然数集{1,2,...}+×以及1形成一个半群。)

答案 1 :(得分:12)

如果我们MonadPlus m成立,那么您说mMonad,而是m a(应用a产生的类型类型"函数" 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)

如果我们使用Monoid

,我们甚至可以定义Haskell -XFlexibleInstances
{-# LANGUAGE FlexibleInstances #-}
instance MonadPlus m => Semigroup (m a) where  (<>) = mplus
instance MonadPlus m => Monoid    (m a) where  zero = mzero

虽然这些与Data.Monoid中的实例严重重叠,这可能是它不是标准实例的原因。


像这样的幺半群的另一个例子是来自Alternative m => m a的{​​{1}}。

答案 2 :(得分:7)

我必须强调非常重要的区别:与Monoid不同,与其他答案不同,MonadPlus 提供具有关联二进制操作和身份的类型。 Haskell报告,唯一可以声明标准状态的文件,没有规定MonadPlus的法律,因此不要求mplus是关联的或mzero 成为它的左或右单位。也许作者仍在辩论法律:mplus有很好的理由不是联想的。例如,如果mplus是关联的但非交换的,那么由MonadPlus表示的非确定性搜索计算可能不完整(即,存在我们无法找到的解决方案)。由于mplus很少是可交换的,所以如果我们坚持关联性,任何完整的非确定性搜索过程都不能由MonadPlus表示。关于SC的MonadPlus法律问题进行了详细讨论:Must mplus always be associative