类型类MonadPlus,替代的和含半幺群之间的区别?类型类MonadPlus,替代的和含半幺群之间

2019-05-13 12:38发布

标准库的Haskell类型类MonadPlusAlternative ,和Monoid各自提供两种方法具有基本相同的语义:

  • 空值: mzeroempty ,或mempty
  • 操作者a -> a -> a ,在类型类一起加入值: mplus<|>mappend

所有这三个指定这些法律,哪些实例应该遵守:

mempty `mappend` x = x
x `mappend` mempty = x

因此,似乎三个类型类都提供相同的方法。

Alternative还提供somemany ,但其默认的定义通常就足够了,所以他们没有在这个问题上来讲太重要了。)

所以,我的查询是:为什么有这三个非常相似的类? 他们之间有任何真正的区别,除了他们不同的超限制?

Answer 1:

MonadPlusMonoid服务于不同目的。

一个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(如果还没有的语言标准)。

实际上, AlternativeApplicative什么MonadPlusMonad

对于这些问题,我们会得到

empty <*> m = empty

类似于我们所拥有的与MonadPlus且存在类似的分配和捕捉性能,其中至少有一个,你应该满足。

不幸的是,甚至empty <*> m = empty法太强索赔。 它并不适用于向后 ,比如!

当我们看MonadPlus,空>> = F =空法几乎被强加给我们。 空结构不能有任何“一个在它调用函数f与反正。

然而,由于Applicative不是一个超MonadAlternative不是一个超MonadPlus ,我们拉闸分别定义两个实例。

此外,即使Applicative是一个超Monad ,你拉闸需要的MonadPlus类反正,因为即使我们服从

empty <*> m = empty

这是不严格不足以证明

empty >>= f = empty

所以声称的东西是MonadPlus比声称这是更强的Alternative

现在,按照惯例, MonadPlusAlternative给定类型应该一致,但Monoid可能是完全不同的。

对于实例MonadPlusAlternativeMaybe做了明显的事情:

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 ,并且在MonadPlusAlternative对于类型实例应该是相关的,所述Monoid可以是(有时是)完全不同的东西。



文章来源: Distinction between typeclasses MonadPlus, Alternative, and Monoid?