Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does mconcat require a list rather than a Foldable?

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)?

like image 683
fphilipe Avatar asked Feb 08 '20 22:02

fphilipe


1 Answers

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.)

like image 86
duplode Avatar answered Nov 10 '22 03:11

duplode