{-| A wrapper for 'Map' with a 'Semigroup' and 'Monoid' instances that delegate to the individual keys. -} module Data.Map.Append.Lazy where import Data.Map.Lazy (Map) import qualified Data.Map.Lazy as Map import Data.Monoid hiding ((<>)) import Data.Semigroup import qualified Data.List.NonEmpty as NE -- | Map wrapper with 'Semigroup' and 'Monoid' instances that delegate to the -- keys. It satisfies the following property: -- -- > lookup k (m1 <> m2) === lookup k m1 <> lookup k m2 -- > where -- > lookup key = Map.lookup key . unAppendMap newtype AppendMap k v = AppendMap { unAppendMap :: Map k v } deriving (Ord, Eq, Show) instance (Ord k, Semigroup v) => Semigroup (AppendMap k v) where AppendMap a <> AppendMap b = AppendMap $ Map.unionWith (<>) a b sconcat = AppendMap . Map.unionsWith (<>) . NE.toList . fmap unAppendMap instance (Ord k, Semigroup v) => Monoid (AppendMap k v) where mempty = AppendMap Map.empty mappend = (<>) mconcat = AppendMap . Map.unionsWith (<>) . fmap unAppendMap