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 fold
from Foldable
.
In fact, mconcat
might be of some use as an implementation of fold @[_]
, 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, Monoid
itself was, though a carefully planned process, reworked in order to add Semigroup
as a superclass, which may or may not support my point.)
The specialised type of mconcat
is 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 both mempty
and mappend
in terms of mconcat
.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With