
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. If anything, what's atypical here is that "emptyBag" has the type in its name. With many other types we have: empty :: ByteString empty :: ByteString.Builder empty :: Map k v empty :: Set a empty :: Seq a empty :: Text empty :: Vector a ... when the type is a Monoid, it is much simpler to just use mempty. -- Viktor.