标准库Haskell MonadPlus、Alternative和Monoid各自提供了两个语义基本相同的方法:
mzero、empty或mempty。a -> a -> a:mplus、<|>或mappend。这三项法律都具体规定了实例应遵守的这些法律:
mempty `mappend` x = x
x `mappend` mempty = x因此,这三个类型的人似乎都提供了相同的方法。
(Alternative还提供了some和many,但是它们的默认定义通常是足够的,因此它们在这个问题上并不太重要。)
所以,我的疑问是:为什么这三个类非常相似?除了它们不同的超类约束之外,它们之间还有什么真正的区别吗?
发布于 2012-04-16 02:36:32
MonadPlus 和 Monoid 的用途不同。
Monoid是在一种类型的*上参数化的。
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但是还有另外两个相互竞争的扩展,即左(sic)分布律。
mplus a b >>= k = mplus (a >>= k) (b >>= k)左边的渔获法
mplus (return a) b = return a因此,MonadPlus的任何实例都应该满足这两个附加定律中的一个或两个。
Alternative**?**:,那么呢?
Applicative是在Monad之后定义的,在逻辑上属于Monad的一个超类,但在很大程度上是由于Haskell 98的设计者所承受的压力不同,直到2015年Functor也不是Monad的超类。现在,我们终于在GHC中将Applicative作为Monad的超类(如果还没有在语言标准中)。
实际上,Alternative对于Applicative来说就像MonadPlus对于Monad一样。
为了这些我们会得到
empty <*> m = empty类似于我们对MonadPlus所拥有的,并且存在类似的分布和捕获属性,至少您应该满足其中的一个属性。
不幸的是,即使是empty <*> m = empty法也过于有力。例如,它不适用于倒着!
当我们看MonadPlus时,空>>= f=空律几乎是强加在我们身上的。空结构中不能有任何‘a’来调用函数f。
但是,由于Applicative不是Monad的超类,Alternative也不是MonadPlus的超类,所以我们最终分别定义了两个实例。
此外,即使Applicative是Monad的超类,您最终还是需要MonadPlus类,因为即使我们遵守了
empty <*> m = empty严格来说,这还不足以证明
empty >>= f = empty因此,声称某物是MonadPlus比声称它是Alternative更强大。
现在,按照惯例,对于给定类型的MonadPlus和Alternative应该是一致的,但是Monoid可能完全不同。
例如,MonadPlus和Alternative For Maybe做了显而易见的事情:
instance MonadPlus Maybe where
mzero = Nothing
mplus (Just a) _ = Just a
mplus _ mb = mb但是Monoid实例将一个半群提升为一个Monoid。可悲的是,因为在Haskell 98中当时还没有一个Semigroup类,所以它需要一个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 = NothingTL; MonadPlus博士是一个比Alternative更强的主张,这反过来又是一个比Monoid更强的主张,虽然一种类型的MonadPlus和Alternative实例应该是相关的,但Monoid可能是(有时也是)完全不同的东西。
https://stackoverflow.com/questions/10167879
复制相似问题