{-# LANGUAGE FlexibleInstances , UndecidableInstances #-} 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)