
Viktor Dukhovni
On Wed, Apr 14, 2021 at 06:26:38PM +0000, Richard Eisenberg wrote:
In the work on simplifying the error-message infrastructure (heavy lifting by Alfredo, in cc), I've been tempted (twice!) to add
instance Semigroup (Bag a) where (<>) = unionBags
instance Monoid (Bag a) where mempty = emptyBag
to GHC.Data.Bag.
I agree that the new Monoid is appropriate.
The downside to writing these is that users might be tempted to write e.g. mempty instead of emptyBag, while the latter gives more information to readers and induces less manual type inference (to a human reader). The upside is that it means Bags work well with Monoid-oriented functions, like foldMap.
I don't see the possibility of writing `mempty` as an issue. I find myself not infrequently writing `mempty` for, e.g., empty ByteStrings, rather than ByteString.empty, because while there are lots of type-specific "empties", they often need to be used qualified, while the polymorphic `mempty` is both clear and flexible.
I think the "clear" is where some might disagree. It has been argued in the past (fairly convincingly, in my opinion) that there is value in being explicit what concrete type an expression has. Afterall, understanding GHC is already hard enough; there's no reason to make it harder by forcing the reader to do type inference. This is why GHC has historically preferred concrete interfaces to using things like mempty. Cheers, - Ben