module Data.Monoid.Union
( module Data.Monoid.Reducer
, HasUnion
, empty
, union
, Union(Union,getUnion)
, HasUnionWith
, emptyWith
, unionWith
, UnionWith(UnionWith,getUnionWith)
) where
import qualified Data.IntMap as IntMap
import Data.IntMap (IntMap)
import qualified Data.IntSet as IntSet
import Data.IntSet (IntSet)
import qualified Data.Map as Map
import Data.Map (Map)
import qualified Data.Set as Set
import Data.Set (Set)
import qualified Data.List as List
import Control.Functor.Pointed
import Data.Monoid.Reducer
class HasUnion f where
empty :: f
union :: f -> f -> f
instance HasUnion (IntMap a) where
empty = IntMap.empty
union = IntMap.union
instance Ord k => HasUnion (Map k a) where
empty = Map.empty
union = Map.union
instance Eq a => HasUnion [a] where
empty = []
union = List.union
instance Ord a => HasUnion (Set a) where
empty = Set.empty
union = Set.union
instance HasUnion IntSet where
empty = IntSet.empty
union = IntSet.union
newtype Union f = Union { getUnion :: f }
deriving (Eq,Ord,Show,Read)
instance (HasUnion f) => Monoid (Union f) where
mempty = Union empty
Union a `mappend` Union b = Union (a `union` b)
instance (HasUnion f) => Reducer f (Union f) where
unit = Union
instance Functor Union where
fmap f (Union a) = Union (f a)
instance Pointed Union where
point = Union
instance Copointed Union where
extract = getUnion
class Functor f => HasUnionWith f where
unionWith :: (a -> a -> a) -> f a -> f a -> f a
emptyWith :: f a
instance HasUnionWith IntMap where
emptyWith = IntMap.empty
unionWith = IntMap.unionWith
instance Ord k => HasUnionWith (Map k) where
emptyWith = Map.empty
unionWith = Map.unionWith
newtype UnionWith f m = UnionWith { getUnionWith :: f m }
deriving (Eq,Ord,Show,Read,Functor,Pointed,Monad)
instance (HasUnionWith f, Monoid m) => Monoid (UnionWith f m) where
mempty = UnionWith emptyWith
UnionWith a `mappend` UnionWith b = UnionWith (unionWith mappend a b)
instance (HasUnionWith f, Monoid m) => Reducer (f m) (UnionWith f m) where
unit = UnionWith