This question already has answers here:
Why MonadPlus and not Monad + Monoid?

(3个答案)


5年前关闭。




我对MonadsMonoids都很陌生,最近还了解了MonadPlus。从我看来,MonoidMonadPlus都提供了具有关联二进制运算和标识的类型。 (在数学上,我将其称为半群。)那么MonoidMonadPlus有什么区别?

最佳答案

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,以便它不会出现在mnp中)。

如果我们将>>专门化为m a -> m a -> m a类型(用b代替a),我们会看到对于任何类型a而言,>>操作在m a上形成了一个半群。 既然对于任何a都是如此,我们得到了一个由a索引的半群类。但是,它们通常不是monoid的-我们没有>>的标识元素。

MonadPlus和monoid
MonadPlus添加了另外两个操作,mplusmzero MonadPlus laws明确声明mplusmzero必须在m a上对任意a形成一个monoid。再一次,我们得到一类由a索引的monoid。

注意MonadPlusMonoid之间的区别:Monoid说某种单一类型满足单调规则,而MonadPlus说对于所有可能的am a类型都满足单调律。这是一个更强的条件。

因此,MonadPlus实例形成了两种不同的代数结构:一类是>>的半群,另一类是mplusmzero的monoid。 (这并不罕见,例如,大于零的自然数集合{1,2,...}+组成一个半群,而与×1组成一个monoid。)

关于haskell - Monoid vs MonadPlus ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17056881/

10-13 06:04