module Data.SetMap (
SetMap,
null,
size,
numKeys,
numValues,
member,
notMember,
lookup,
(!),
empty,
insert,
delete,
map,
elems,
keys,
toMap,
) where
import Prelude hiding (lookup, map, null, foldr, foldl)
import qualified Prelude as P
import qualified Data.Set as Set
import Data.Set (Set)
import qualified Data.Map as Map
import Data.Map (Map)
import Data.Word
import Data.Data
newtype SetMap k v = SetMap (Word32, Word32, Map k (Set v))
deriving (Data, Typeable)
null :: SetMap k a -> Bool
null (SetMap (_, _, m)) = Map.null m
size :: SetMap k a -> Int
size (SetMap (_, size, _)) = fromIntegral size
numKeys :: SetMap k a -> Word32
numKeys (SetMap (nk, _, _)) = nk
numValues :: SetMap k a -> Word32
numValues (SetMap (_, nv, _)) = nv
notMember, member :: Ord k => SetMap k a -> k -> Bool
member (SetMap (_, _, map)) key = Map.member key map
notMember key = not . member key
(!) :: Ord k => SetMap k a -> k -> Set a
(!) = flip lookup
lookup :: Ord k => k -> SetMap k a -> Set a
lookup key (SetMap (_, _, map)) = maybe Set.empty id (Map.lookup key map)
empty :: SetMap k a
empty = SetMap (0, 0, Map.empty)
insert :: (Ord k, Ord a) => k -> a -> SetMap k a -> SetMap k a
insert k v (SetMap (nk, nv, map))
| Map.member k map =
let oldSet = map Map.! k
(nv', newSet) = if v `Set.member` oldSet
then (nv, oldSet) else (succ nv, v `Set.insert` oldSet)
in SetMap (nk, nv', Map.insert k newSet map)
| otherwise = SetMap (succ nk, succ nv, Map.insert k (Set.singleton v) map)
delete :: Ord k => k -> SetMap k a -> SetMap k a
delete k m@(SetMap (nk, nv, map)) = case Map.lookup k map of
Just v -> SetMap (pred nk, nv fromIntegral (Set.size v), Map.delete k map)
_ -> m
map :: (Ord a, Ord b) => (a -> b) -> SetMap k a -> SetMap k b
map f (SetMap (nk, nv, map)) = SetMap (nk, nv, Map.map (Set.map f) map)
elems :: SetMap k a -> [[a]]
elems (SetMap (_, _, map)) = P.map (Set.elems) $ Map.elems map
keys :: SetMap k a -> [k]
keys (SetMap (_, _, map)) = Map.keys map
toMap :: SetMap k a -> Map k (Set a)
toMap (SetMap (_, _, theUnderlyingMap)) = theUnderlyingMap