module Data.Mergeable where
import Data.Commutative
import Data.List.NonEmpty as NE
class Mergeable t where
mergeMap :: CommutativeId m => (a -> m) -> t a -> m
merge :: (a -> b -> b) -> b -> t a -> b
mergeMap f = merge (commute . f) cempty
merge f i xs = appCommEndo (mergeMap (CommEndo . f) xs) i
instance Mergeable [] where
mergeMap _ [] = cempty
mergeMap f (x:xs) = f x <~> mergeMap f xs
class Functor t => Mergeable1 t where
mergeMap1 :: Commutative m => (a -> m) -> t a -> m
merge1 :: Commutative m => t m -> m
mergeMap1 f = merge1 . fmap f
merge1 = mergeMap1 id
instance Mergeable1 NonEmpty where
mergeMap1 f (x:|[]) = f x
mergeMap1 f (x:|xs) = f x <~> mergeMap1 f (NE.fromList xs)