标准库的Haskell类型类MonadPlus,Alternative以及Monoid各自提供两种方法具有基本相同的语义:
mzero,empty或mempty.a -> a -> a,在类型类联接值加在一起:mplus,<|>或mappend.所有这三个都规定了应遵守的法律:
mempty `mappend` x = x
x `mappend` mempty = x
Run Code Online (Sandbox Code Playgroud)
因此,似乎三个类型都提供相同的方法.
(Alternative也提供some和many,但它们的默认定义通常是足够的,所以它们在这个问题上并不太重要.)
所以,我的疑问是:为什么这三个极为相似的类?除了不同的超类限制之外,它们之间是否有任何真正的区别?
haskell functional-programming typeclass applicative monoids
我听说Haskell的"破坏"约束系统存在一些问题,如GHC 7.6及以下版本.它出什么问题了?是否有可比的现有系统克服了这些缺陷?
例如,edwardk和tekmo都遇到了麻烦(例如来自tekmo的评论).
module StackOverflow where -- yes, the source of this post compiles as is
Run Code Online (Sandbox Code Playgroud)
如果您想先玩这个(1/2向下),请跳到下面的操作以使其正常工作.如果我稍微
停下来,你会跳到我想要的东西,你只想找到我正在寻求的帮助.
:so我在我定义的命令中ghci.conf吗? :l可以用于.hs和.lhs像往常一样的文件,但使用我的手写预处理器的.so文件?Haskell支持.lhs源文件中的文字编程,有两种方式:
\begin{code}和\end{code}.>,其他任何东西都是评论.>).Bird不跟踪类似于StackOverflow代码块的规则声音吗?
参考文献: 1. 将.ghci手册
2. GHCI haskellwiki
3. 关于尼尔·米切尔的博客:{,并:}在.ghci
我喜欢在文本编辑器中编写SO答案,我喜欢发表一个包含有效代码的帖子,但最后还是>在发布之前我必须编辑的注释块或者s,这不那么有趣.
所以,我自己写了一个预处理器.
*或开头:. …如上所述这个问题/答案,Functor实例唯一确定的,如果他们存在.
对于列表,有两个众所周知的Applicative实例:[]和ZipList.因此,应用型不是唯一的(见GHC可以导出函子与应用型实例的单子变压器?而且为什么没有-XDeriveApplicative推广?).但是,ZipList需要无限列表,因为它pure无限期地重复给定元素.
Applicative实例?去进一步,如果我们能够扩大双方[]和ZipList一个单子,我们会在那里有一个单子不是唯一的数据类型和其确定的函数对象的例子.唉,只有当我们将自己限制在无限列表(流)时才有ZipList Monad实例.并且为了创建单元素列表,所以它需要有限列表.因此:return[]
如果有一个包含两个或更多不同实例的示例,则会出现一个明显的问题,如果它们必须/可以具有相同的Applicative实例:
最后我们可以为Alternative/MonadPlus提出同样的问题.由于存在两组不同的MonadPlus法则,这很复杂.假设我们接受一套法律(对于Applicative我们接受右/左分配/吸收,也参见这个问题),
如果以上任何一个都是独一无二的,我会有兴趣知道为什么,要有一丝证明.如果没有,反例.
在他的回答这个问题"类型类之间的区别MonadPlus,Alternative以及Monoid?",爱德华Kmett说,
而且,即使
Applicative是超级课程Monad,你最终还是需要MonadPlus上课,因为顺从Run Code Online (Sandbox Code Playgroud)empty <*> m = empty并不足以证明这一点
Run Code Online (Sandbox Code Playgroud)empty >>= f = empty因此声称某事物是一件事,
MonadPlus比宣称事情要强Alternative.
很明显,任何适用函子是不是一个单子是自动的一个例子Alternative是不是MonadPlus,但爱德华Kmett的回答意味着存在一个单子这是一个Alternative,但不是一个MonadPlus:它empty和<|>将满足Alternative法律,1而不是MonadPlus法律.2 我自己无法想出这样的例子; 有人知道吗?
1我无法找到一套规则的规范参考Alternative,但是我将我认为它们的内容大概放在我对" 类型类的含义及其与其他类型的关系的混淆"这一问题的答案的中间.类"(搜索短语"正确的分配").我认为应该遵守的四项法律是:Alternative
<*>: (f …我对这两者都很陌生Monads,Monoids而且最近也学到了MonadPlus.从我所看到的,Monoid并MonadPlus都提供了二元结合运算和身份类型.(我用数学的说法称之为半群.)那么Monoid和之间的区别是MonadPlus什么?
哪些功能some和many在Alternative类型类有用吗?Docs提供了一个我无法理解的递归定义.
有一个实例Monoid a => Monoid (Const a b)为Const从仿函数Control.Applicative.还有一个例子Monoid m => Applicative (Const m).
因此,我希望还有一个实例Monoid m => Alternative (Const m)与之相符Monoid.这只是一个应该修复的遗漏,还是有更深层次的原因?
ZipList附带一个Functor和一个Applicative实例(Control.Applicative),但为什么不选择Alternative?
Bool可通过两种方式幺半群),因此也不应该是的实例我搜索了"实例替代ZipList"(用引号查找代码优先)并且只找到了库,一些教程,讲义而没有实际的实例.
马特芬威克说,如果A是,则ZipList A只会是一个幺半群.看到这里.无论元素类型如何,列表都是幺半群.
AndrewC对同一问题的另一个答案讨论了Alternative实例的外观.他说
Zip有两个合理的选择
[1,3,4] <|> Zip [10,20,30,40]:
Zip [1,3,4]因为它是第一个 - 与Maybe一致Zip [10,20,30,40]因为它是最长的 - 与Zip []丢弃一致
Zip基本上是ZipList.我认为答案应该是Zip [1,3,4,40].我们来看一个实例:
instance Aternative Zip where
empty = Zip []
Zip xs <|> Zip ys = Zip (go xs ys) where
go [] ys = ys
go (x:xs) ys = x : go xs (drop 1 ys)
Run Code Online (Sandbox Code Playgroud)
唯一Zip …
为什么guard基于Alternative?
guard :: Alternative f => Bool -> f ()
-- guard b is pure () if b is True,
-- and empty if b is False.
Run Code Online (Sandbox Code Playgroud)
我问因为guard只使用了empty来自Alternative.它不使用<|>从Alternative根本.那么为什么要Alternative首先使用呢?
我想这是因为背后有一些不成文的想法Alternative的empty,与我们正在努力与实现的目标完全吻合guard(停止False,继续True).如果是这种情况,请告诉我这个没有说明的想法.
但与此同时,如果觉得我们只是在忽视<|>.感觉好像guard不是"完全捕捉"到底Alternative是什么.我希望这是有道理的.为了使它更具体:为什么他们不发明另一个类似Stoppable(或Abortable)之类的类型并使用它而不是Alternative?