我一直在浏览Typeclassopedia来学习类型类.我不理解Alternative(MonadPlus就此而言).
我遇到的问题:
'pedia说"替代类型类适用于具有幺半群结构的Applicative仿函数." 我不明白 - 不是替代意味着与Monoid完全不同的东西吗?也就是说,我理解了替代类型类在两件事之间的选择,而我理解Monoids是关于组合事物.
为什么Alternative需要一个empty方法/成员?我可能错了,但似乎根本没有使用...至少在我能找到的代码中.它似乎不符合课堂主题 - 如果我有两件事,需要选择一件,我需要什么'空'?
为什么Alternative类需要一个Applicative约束,为什么它需要一种* -> *?为什么不<|> :: a -> a -> a呢?所有的实例仍然可以用同样的方式实现......我想(不确定).Monoid没有提供什么价值?
什么是点MonadPlus式类?我不能解开所有善良的通过只是使用的东西既是Monad和Alternative?为什么不放弃呢?(我确定我错了,但我没有任何反例)
希望所有这些问题都是连贯的......!
赏金更新:@Antal的答案是一个很好的开始,但Q3仍然是开放的:替代品提供的Monoid不是什么?我发现这个答案不能令人满意,因为它缺乏具体的例子,并且特别讨论了Alternative的高知名度如何将它与Monoid区分开来.
如果要将应用效果与Monoid的行为结合起来,为什么不只是:
liftA2 mappend
Run Code Online (Sandbox Code Playgroud)
这对我来说更加令人困惑,因为许多Monoid实例与Alternative实例完全相同.
这就是为什么我要寻找具体的例子,说明为什么备选是必要的,以及它与Monoid的不同之处 - 或者意味着不同的东西.
我正在使用" 第一原理的Haskell编程 " 一书来学习Haskell ,并且在第4章"基本数据类型"的末尾,我遇到了让我感到困惑的事情.这本书提到了一个功能,length并说它适用于Listss.一切都很好,但是当我length用各种Tuples 尝试这个功能时,我看到的东西让我很困惑:
首先,让我们看看类型length:
:t length
length :: Foldable t => t a -> Int
Run Code Online (Sandbox Code Playgroud)
好的,所以我在上面读到"带一个可折叠的,我认为这是一个方便的列表,并返回一个Int,即列表中元素的数量." 因此,我的第一个困惑:为什么以下工作:
length (1, 1)
1
Run Code Online (Sandbox Code Playgroud)
因为对我而言,似乎我刚刚传递了一个带有两个元素的元组length,它返回1.是元组列表吗?元组是否可折叠?当然,为什么1呢?
现在我更进一步:
length (1, 1, 1)
<interactive>:6:1:
No instance for (Foldable ((,,) t0 t1))
arising from a use of ‘length’
In the expression: length (1, 1, 1)
In an equation for ‘it’: it = length (1, 1, 1)
<interactive>:6:9:
No instance …Run Code Online (Sandbox Code Playgroud) 在他的回答这个问题"类型类之间的区别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,Functors和Applicatives有关的功能.
示例(从大多数到最不通用):
fmap == liftA == liftM
(<*>) == ap
liftA[2345] == liftM[2345]
pure == return
(*>) == (>>)
Run Code Online (Sandbox Code Playgroud)
不直接基于FAM类树的示例:
fmap == map
Run Code Online (Sandbox Code Playgroud)
(我认为List,Foldable,Traversable还有很多,但看起来大部分时间都变得更通用了,因为我只看到旧堆栈溢出/留言板问题中旧的,不太通用的类型签名)
我个人觉得这很烦人,因为这意味着如果我需要做x,而某些函数如liftM允许我做x,那么我会使我的函数不那么通用,而且我只会去通过彻底推断类型之间的差异(例如FAM,或者可能是List,Foldable,Traversable组合)来注意那种事情,这对于初学者来说并不友好,因为简单地使用这些类型并不是那么难,关于他们的属性和法律的推理需要更多的心理努力.
我猜这些等价物很多都来自于申请Monad提案.如果这就是他们的原因(并且由于可用于混淆的通用功能较少而缺少其他原因),他们是否会被弃用/删除?由于破坏现有代码,我可以理解等待很长时间才能删除它们,但肯定会弃用是个好主意吗?