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