Why does mconcat require a list rather than a Foldable?
Asked Answered
F

1

9

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

Farina answered 8/2, 2020 at 22:50 Comment(1)
The old version of foldr only worked on lists iirc.Florencio
D
10

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

Diffusion answered 8/2, 2020 at 23:34 Comment(1)
Thanks for this list, really helpful! Just realized that I could have found fold myself by simply hoogling (Foldable t, Monoid m) => t m -> m. I also came across an interesting article titled Synonyms in base, which lists this and other examples of similar functions.Farina

© 2022 - 2024 — McMap. All rights reserved.