标准库的Haskell类型类MonadPlus
, Alternative
,和Monoid
各自提供两种方法具有基本相同的语义:
- 空值:
mzero
, empty
,或mempty
。 - 操作者
a -> a -> a
,在类型类一起加入值: mplus
, <|>
或mappend
。
所有这三个指定这些法律,哪些实例应该遵守:
mempty `mappend` x = x
x `mappend` mempty = x
因此,似乎三个类型类都提供相同的方法。
( Alternative
还提供some
与many
,但其默认的定义通常就足够了,所以他们没有在这个问题上来讲太重要了。)
所以,我的查询是:为什么有这三个非常相似的类? 他们之间有任何真正的区别,除了他们不同的超限制?
MonadPlus
和Monoid
服务于不同目的。
一个Monoid
被参数在类型种类*
。
class Monoid m where
mempty :: m
mappend :: m -> m -> m
因此它可以被实例化用于几乎任何类型的针对其存在一个明显的操作符是关联的,并且其具有的单元。
然而, MonadPlus
不仅规定了你有一个monoidal结构,也表明该结构是关系到如何Monad
工作, 而且该结构不关心包含在单子的价值,这是(部分)的指示事实上, MonadPlus
需要类型的参数* -> *
。
class Monad m => MonadPlus m where
mzero :: m a
mplus :: m a -> m a -> m a
除了独异的法律,我们有我们可以申请法律两个潜在的套MonadPlus
。 可悲的是,社区不同意为它们应该是什么。
在至少我们知道
mzero >>= k = mzero
但也有其他两个竞争的延伸,左(原文如此)的分布规律
mplus a b >>= k = mplus (a >>= k) (b >>= k)
和左捕法
mplus (return a) b = return a
所以任何实例MonadPlus
应该满足这些额外的法律的一个或两个。
那么,关于Alternative
?
Applicative
被定义后Monad
,并且在逻辑上属于作为的超Monad
,但主要是由于对设计师早在哈斯克尔98不同的压力,甚至Functor
是不是一个超Monad
,直到2015年。现在,我们终于有了Applicative
作为超的Monad
在GHC(如果还没有的语言标准)。
实际上, Alternative
是Applicative
什么MonadPlus
是Monad
。
对于这些问题,我们会得到
empty <*> m = empty
类似于我们所拥有的与MonadPlus
且存在类似的分配和捕捉性能,其中至少有一个,你应该满足。
不幸的是,甚至empty <*> m = empty
法太强索赔。 它并不适用于向后 ,比如!
当我们看MonadPlus,空>> = F =空法几乎被强加给我们。 空结构不能有任何“一个在它调用函数f
与反正。
然而,由于Applicative
是不是一个超Monad
和Alternative
是不是一个超MonadPlus
,我们拉闸分别定义两个实例。
此外,即使Applicative
是一个超Monad
,你拉闸需要的MonadPlus
类反正,因为即使我们服从
empty <*> m = empty
这是不严格不足以证明
empty >>= f = empty
所以声称的东西是MonadPlus
比声称这是更强的Alternative
。
现在,按照惯例, MonadPlus
和Alternative
给定类型应该一致,但Monoid
可能是完全不同的。
对于实例MonadPlus
和Alternative
的Maybe
做了明显的事情:
instance MonadPlus Maybe where
mzero = Nothing
mplus (Just a) _ = Just a
mplus _ mb = mb
但Monoid
实例举一个半群成Monoid
。 可悲的是,因为不存在一个Semigroup
在Haskell 98的时候类,它通过一个requring这样做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 = Nothing
TL; DR MonadPlus
比更强的权利要求Alternative
,这又是比更强的权利要求Monoid
,并且在MonadPlus
和Alternative
对于类型实例应该是相关的,所述Monoid
可以是(有时是)完全不同的东西。