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

fph*_*ipe 8 haskell monoids foldable

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

mconcat :: Monoid a => [a] -> a
mconcat = foldr mappend mempty
Run Code Online (Sandbox Code Playgroud)

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

mconcat' :: (Foldable t, Monoid a) => t a -> a
mconcat' = foldr mappend mempty
Run Code Online (Sandbox Code Playgroud)

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

dup*_*ode 8

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

  • 泛化函数已存在于foldfromFoldable

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

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

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