While looking at the definition of Monoid I noticed that mconcat has the following definition (source):
mconcat :: Monoid a => [a] -> a
mconcat = foldr mappend mempty
Why would the signature limit this to [a] rather than the more generic Foldable like this?
mconcat' :: (Foldable t, Monoid a) => t a -> a
mconcat' = foldr mappend mempty
Is this for historical reasons? Or would this more generic implementation make it harder for specific types to provide an optimized version of it, as is the case e.g. for [] which uses list comprehension (source)?
Though I don't know of an actual discussion about such a proposal, here are some conceivable reasons:
The generalised function already exists as
foldfromFoldable.In fact,
mconcatmight be of some use as an implementation offold @[_], which might be more efficient than the usual default for some monoids. (I took this idea from GHC issue #17123.)Changing class method signatures leads to churn, as instances everywhere must be adjusted accordingly, and so it tends to be done only when there is a pressing need. (By the way,
Monoiditself was, though a carefully planned process, reworked in order to addSemigroupas a superclass, which may or may not support my point.)The specialised type of
mconcatis meaningful, reflecting how the list type is an encoding of the free monoid in Haskell. (Another interesting factoid is that it is possible to implement bothmemptyandmappendin terms ofmconcat.)