Proposal: Remove Semigroup and Monoid instances for Data.Map, Data.IntMap, Data.HashMap

Akio Takano tkn.akio at
Wed Feb 14 08:49:04 UTC 2018

Hi David,

On 13 February 2018 at 19:33, David Feuer <david.feuer at> wrote:
> Many people have recognized for years that the Semigroup and Monoid
> instances for Data.Map, Data.IntMap, and Data.HashMap are not so
> great. In particular, when the same key is present in both maps, they
> simply use the value from the first argument, ignoring the other one.
> This somewhat counter-intuitive behavior can lead to bugs. See, for
> example, the discussion in Tim Humphries's blog post[*]. I would like
> do do the following:

I'm against this proposal because I think the improvement is, if not
negative, too small to justify breaking existing code.

I can think of 3 reasonable definitions for (<>) for lazy maps:

1. (<>) = union
2. (<>) = unionWith (<>)
3. (<>) = Strict.unionWith (<>)

Of these, (1) is by far the most useful operation in my experience.
(2) has the advantage that it seems like the most obvious choice, but
it's not very useful in practice. (3) is slightly more useful than
(2), but feels less canonical. Also (3) seems inconsistent with how
fmap is defined.

So there doesn't seem to be a clear winner. Perhaps there shouldn't
have been a Monoid instance for maps in the first place. Given that we
already have one, however, it seems that the marginal gain of removing
it doesn't justify the cost of breaking code.

(If the removal is going to happen anyway, I vote for not adding back
any instance.)

Takano Akio

More information about the Libraries mailing list