{-# LANGUAGE UndecidableInstances, OverlappingInstances, FlexibleInstances,
MultiParamTypeClasses, TemplateHaskell, PolymorphicComponents,
DeriveDataTypeable,ExistentialQuantification #-}
module Data.IxSet.Ix
( Ix(..)
, insert
, delete
, insertList
, deleteList
, union
, intersection
)
where
import Data.Generics hiding (GT)
import qualified Data.Generics.SYB.WithClass.Basics as SYBWC
import Data.List (foldl')
import Data.Map (Map)
import qualified Data.Map.Strict as Map
import Data.Set (Set)
import qualified Data.Set as Set
data Ix a = forall key . (Typeable key, Ord key) =>
Ix (Map key (Set a)) (a -> [key])
deriving Typeable
instance Data a => Data (Ix a) where
toConstr (Ix _ _) = con_Ix_Data
gunfold _ _ = error "gunfold"
dataTypeOf _ = ixType_Data
con_Ix_Data :: Constr
con_Ix_Data = mkConstr ixType_Data "Ix" [] Prefix
ixType_Data :: DataType
ixType_Data = mkDataType "Happstack.Data.IxSet.Ix" [con_Ix_Data]
ixConstr :: SYBWC.Constr
ixConstr = SYBWC.mkConstr ixDataType "Ix" [] SYBWC.Prefix
ixDataType :: SYBWC.DataType
ixDataType = SYBWC.mkDataType "Ix" [ixConstr]
instance (SYBWC.Typeable Ix, SYBWC.Data ctx a, SYBWC.Sat (ctx (Ix a)))
=> SYBWC.Data ctx (Ix a) where
gfoldl _ _ _ _ = error "gfoldl Ix" :: w (Ix a)
toConstr _ (Ix _ _) = ixConstr
gunfold _ _ _ _ = error "gunfold Ix" :: c (Ix a)
dataTypeOf _ _ = ixDataType
insert :: (Ord a, Ord k)
=> k -> a -> Map k (Set a) -> Map k (Set a)
insert k v index = Map.insertWith Set.union k (Set.singleton v) index
insertList :: (Ord a, Ord k)
=> [(k,a)] -> Map k (Set a) -> Map k (Set a)
insertList xs index = foldl' (\m (k,v)-> insert k v m) index xs
delete :: (Ord a, Ord k)
=> k -> a -> Map k (Set a) -> Map k (Set a)
delete k v index = Map.update remove k index
where
remove set = let set' = Set.delete v set
in if Set.null set' then Nothing else Just set'
deleteList :: (Ord a, Ord k)
=> [(k,a)] -> Map k (Set a) -> Map k (Set a)
deleteList xs index = foldl' (\m (k,v) -> delete k v m) index xs
union :: (Ord a, Ord k)
=> Map k (Set a) -> Map k (Set a) -> Map k (Set a)
union index1 index2 = Map.unionWith Set.union index1 index2
intersection :: (Ord a, Ord k)
=> Map k (Set a) -> Map k (Set a) -> Map k (Set a)
intersection index1 index2 = Map.filter (not . Set.null) $
Map.intersectionWith Set.intersection index1 index2