So I went through the whole process of defining newtype, but it was quite a long process. My code below.
Surely it would make more sense if the HashMap monoid were defined in terms of the monoid of its value type?
In that case you could choose the monoid for the value to take the left value, which would be the equivalent of the current behaviour.
import qualified Control.Applicative as A
import Data.Hashable
import qualified Data.HashMap.Lazy as M
import Data.Monoid
newtype HashMap k v = HashMap (M.HashMap k v)
instance (Eq k, Hashable k, Monoid v) => Monoid (HashMap k v) where
mempty = empty
mappend (HashMap a) (HashMap b) = HashMap (M.unionWith mappend a b)
empty :: HashMap k v
empty = HashMap M.empty
singleton :: Hashable k => k -> v -> HashMap k v
singleton k v = HashMap (M.singleton k v)
null :: HashMap k v -> Bool
null (HashMap m) = M.null m
size :: HashMap k v -> Int
size (HashMap m) = M.size $ m
member :: (Eq k, Hashable k) => k -> HashMap k a -> Bool
member k (HashMap m) = M.member k m
lookup :: (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
lookup k (HashMap m) = M.lookup k m
lookupDefault :: (Eq k, Hashable k) => v -> k -> HashMap k v -> v
lookupDefault v k (HashMap m) = M.lookupDefault v k m
(!) :: (Eq k, Hashable k) => HashMap k v -> k -> v
(!) (HashMap m) k = (M.!) m k
insert :: (Eq k, Hashable k) => k -> v -> HashMap k v -> HashMap k v
insert k v (HashMap m) = HashMap (M.insert k v m)
insertWith :: (Eq k, Hashable k) => (v -> v -> v) -> k -> v -> HashMap k v -> HashMap k v
insertWith f k v (HashMap m) = HashMap (M.insertWith f k v m)
delete :: (Eq k, Hashable k) => k -> HashMap k v -> HashMap k v
delete k (HashMap m) = HashMap $ M.delete k m
adjust :: (Eq k, Hashable k) => (v -> v) -> k -> HashMap k v -> HashMap k v
adjust f k (HashMap m) = HashMap $ M.adjust f k m
union :: (Eq k, Hashable k) => HashMap k v -> HashMap k v -> HashMap k v
union (HashMap a) (HashMap b) = HashMap (M.union a b)
unionWith :: (Eq k, Hashable k) => (v -> v -> v) -> HashMap k v -> HashMap k v -> HashMap k v
unionWith f (HashMap a) (HashMap b) = HashMap (M.unionWith f a b)
unions :: (Eq k, Hashable k) => [HashMap k v] -> HashMap k v
unions ms = HashMap (M.unions [un m | m <- ms])
where un (HashMap m) = m
map :: (v1 -> v2) -> HashMap k v1 -> HashMap k v2
map f (HashMap m) = HashMap (M.map f m)
--mapWithKey :: (k -> v1 -> v2) -> HashMap k v1 -> HashMap k v2
--mapWithKey f (HashMap m) = HashMap (M.mapWithKey f m)
traverseWithKey :: A.Applicative f => (k -> v1 -> f v2) -> HashMap k v1 -> f (HashMap k v2)
traverseWithKey f (HashMap m) = HashMap `fmap` (M.traverseWithKey f m)
difference :: (Eq k, Hashable k) => HashMap k v -> HashMap k w -> HashMap k v
difference (HashMap a) (HashMap b) = HashMap (M.difference a b)
intersection :: (Eq k, Hashable k) => HashMap k v -> HashMap k w -> HashMap k v
intersection (HashMap a) (HashMap b) = HashMap (M.intersection a b)
intersectionWith :: (Eq k, Hashable k) => (v1 -> v2 -> v3) -> HashMap k v1 -> HashMap k v2 -> HashMap k v3
intersectionWith f (HashMap a) (HashMap b) = HashMap (M.intersectionWith f a b)
foldl' :: (a -> v -> a) -> a -> HashMap k v -> a
foldl' f v (HashMap m) = M.foldl' f v m
foldlWithKey' :: (a -> k -> v -> a) -> a -> HashMap k v -> a
foldlWithKey' f v (HashMap m) = M.foldlWithKey' f v m
foldr :: (v -> a -> a) -> a -> HashMap k v -> a
foldr f v (HashMap m) = M.foldr f v m
foldrWithKey :: (k -> v -> a -> a) -> a -> HashMap k v -> a
foldrWithKey f v (HashMap m) = M.foldrWithKey f v m
filter :: (v -> Bool) -> HashMap k v -> HashMap k v
filter f (HashMap m) = HashMap (M.filter f m)
filterWithKey :: (k -> v -> Bool) -> HashMap k v -> HashMap k v
filterWithKey f (HashMap m) = HashMap (M.filterWithKey f m)
keys :: HashMap k v -> [k]
keys (HashMap m) = M.keys m
elems :: HashMap k v -> [v]
elems (HashMap m) = M.elems m
toList :: HashMap k v -> [(k, v)]
toList (HashMap m) = M.toList m
fromList :: (Eq k, Hashable k) => [(k, v)] -> HashMap k v
fromList kvs = HashMap (M.fromList kvs)
fromListWith :: (Eq k, Hashable k) => (v -> v -> v) -> [(k, v)] -> HashMap k v
fromListWith f kvs = HashMap (M.fromListWith f kvs)