Hi, John.

You can always use newtype wrapper if you need to overload existing method behavior:

newtype MyHashMap a b = MyHashMap { unMy :: HashMap a b}

instance Monoid (MyHasMap a b) where
  mempty = MyHasMap mempty
  mappend a b = your_overloaded_function

Then just wrap and unwrap your data to do a custom mappend, also you can write a wrapper function, in case if you'll restrict types then it may work only for the types you need:

(<~>) :: HashMap Int (HashMap Int Int) -> HashMap Int (HashMap Int Int) -> HashMap Int (HashMap Int Int)
a <~> b = unMy $ (<>) `on` MyHashMap a b

--
Alexander