haskell / haskell/containers

Additional semigroup/monoid instances for Map

Open
#539 24 comments 3 reactions 0 assignees View on GitHub
feature-request Map
Dominant language
Haskell
Stars
355
Forks
194
Avg merge
3d 4h
Merged PRs (30d)
4

Description

I've often found the below a useful semigroup/monoid instance for maps where `m1 <> m2` performs an upsert dependent on the semigroup instance of the value types. If a key exists in both `m1` and `m2` then the new value is `a1 <> a2`, otherwise if the key exists in only one of the maps then the new map takes the corresponding value.

This is useful in configuration like contexts with the `Last a` semigroup.

``` haskell
newtype OptionMap k a = OptionMap { getOptionMap :: M.Map k a }

instance (Ord k, Semigroup a) => Semigroup (OptionMap k a) where
(<>) (OptionMap m1) (OptionMap m2) = OptionMap $ M.unionWith (<>) m1 m2

instance (Ord k, Semigroup a) => Monoid (OptionMap k a) where
mappend = (<>)
mempty = AppendMap mempty
```

As the implementation above shows, this can be easily recovered with `M.unionWith` but you then can't leverage code that works generically over `Semigroup` and `Monoid`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.