为什么 mconcat 需要一个列表而不是一个可折叠的?

Why does mconcat require a list rather than a Foldable?

同时查看Monoid I noticed that mconcat has the following definition (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)?

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

  • 广义函数已存在 fold from Foldable

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

  • 更改class方法签名会导致流失,因为必须相应地调整所有地方的实例,因此只有在有迫切需要时才会这样做。 (顺便说一下,Monoid 本身是 though a carefully planned process,为了将 Semigroup 添加为超级 class 而重新设计,这可能支持也可能不支持我的观点。)

  • mconcat的特化类型是有意义的,体现了。 (另一个有趣的事实是,可以根据 mconcat 来实现 memptymappend。)