8

在查看的定义时,Monoid我注意到mconcat具有以下定义(source):

mconcat :: Monoid a => [a] -> a
mconcat = foldr mappend mempty

为什么签名会将其限制为[a]而不是像这样更通用Foldable

mconcat' :: (Foldable t, Monoid a) => t a -> a
mconcat' = foldr mappend mempty

这是出于历史原因吗?或者这种更通用的实现是否会使特定类型更难提供它的优化版本,例如[]使用列表理解(source)的情况?

4

1 回答 1

9

虽然我不知道关于这样一个提议的实际讨论,但这里有一些可以想象的原因:

  • fold广义函数从Foldable开始就已经存在。

  • 事实上,mconcat作为 的实现可能有一些用途fold @[_],这可能比某些幺半群的通常默认值更有效。(我从GHC 问题 #17123中获得了这个想法。)

  • 更改类方法签名会导致流失,因为各处的实例都必须相应地进行调整,因此只有在迫切需要时才会这样做。(顺便说一句,虽然是一个精心策划的过程Monoid,但它本身是为了添加为超类而重新设计的,这可能支持也可能不支持我的观点。)Semigroup

  • 的特殊类型mconcat是有意义的,反映了列表类型是如何编码 Haskell 中的自由幺半群的。(另一个有趣的事实是,可以同时实现memptymappendmconcat

于 2020-02-08T23:34:56.393 回答