I was doing a bit of work with a Map from purescript-ordered-collections and I needed to combine maps in a way that also combined the values of the map with unionWith (<>)
I ended up writing a newtype to get this behaviour, but it seems like something like this probably exists and I just don’t know how to find it? Maybe I shouldn’t be using a map here at all… (NB: I know Collection is an awful name)
newtype Collection k v = Collection (Map k v)
instance semigroupCollection :: (Semigroup v, Ord k) => Semigroup (Collection k v) where
append (Collection a) (Collection b) = M.unionWith (<>) a b # Collection
instance monoidCollection :: (Ord k, Semigroup (Collection k v)) => Monoid (Collection k v) where
mempty = Collection M.empty
Side note - there is an ongoing discussion to make Semigroup / Monoid instances more flexible by depending on the internal type instance (I’m linking to the specific @goodacre.liam comment there):
This would be more consistent with for example instances of Foreign.Object or Maybe.
We can have an Alt instance (which is missing) in the case of both Data.Map and Foreign.Object which is right-biased (or left-biased) then I think.