Why isn't Data.Map not an instance of Monoid :-)

Adrian Hey ahey at iee.org
Mon May 7 05:23:24 EDT 2007


Hello Folks,

Just been going through making sure the class instances for the
AVL based Data.Map clone make sense, and I find this in Data.Map
(and the clone).

instance (Ord k) => Monoid (Map k v) where
     mempty  = empty
     mappend = union
     mconcat = unions

This worries me because there is no obviously correct choice for the
semantics of union for maps (as in which maps associated values get
dropped).

I've always felt that it was bad practice to provide library functions
which simply make an arbitrary but a significant choice on users behalf,
knowing it's likely that this isn't going to be what 50% of users
actually want.

So I'd been giving serious consideration to deprecating union, thereby
forcing users to specify the behaviour they actually want using
unionWith. The only reason I didn't in the end is that it's easy
enough for users to get what they want in this case using flip
(provided they don't care about "biasing" for keys)

But it's not so easy if functions like this are used as class methods.
So my inclination was to drop the Monoid instance for Maps. But
I see by doing this I break Jean-Philippes instance of the Map
class (which has a Monoid constraint) in the new Collections API..

http://darcs.haskell.org/packages/collections-ghc6.6/Data/Collections.hs

AFAICT Jean-Philippe class only uses mempty, so I had been considering..

instance Ord k => Monoid (Map k v) where
  mempty  = empty
  mappend = error "Data.Map.AVL: undefined Monoid.mappend."
  mconcat = error "Data.Map.AVL: undefined Monoid.mconcat."

However, fooling people into thinking it is a Monoid when it isn't
all so seems bad.

So what do you think about this? Keep it or drop it?
Does anybody (other than Jean-Philippe :-) currently rely on Data.Map
being a Monoid instance?

Regards
--
Adrian Hey



More information about the Libraries mailing list