module Data.MultiMap (
MultiMap,
null,
size,
numKeys,
numValues,
member,
notMember,
lookup,
(!),
empty,
insert,
delete,
map,
mapKeys,
mapWithKey,
foldr,
foldl,
foldrWithKey,
foldlWithKey,
elems,
keys,
keysSet,
assocs,
toMap,
toMapOfSets,
toList,
fromList,
fromMap,
findMin,
findMax,
findMinWithValues,
findMaxWithValues
) 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 MultiMap k v = MultiMap (Word32, Word32, Map k [v])
deriving (Data, Typeable)
null :: MultiMap k a -> Bool
null (MultiMap (_, _, m)) = Map.null m
size :: MultiMap k a -> Int
size (MultiMap (_, size, _)) = fromIntegral size
numKeys :: MultiMap k a -> Word32
numKeys (MultiMap (nk, _, _)) = nk
numValues :: MultiMap k a -> Word32
numValues (MultiMap (_, nv, _)) = nv
notMember, member :: Ord k => MultiMap k a -> k -> Bool
member (MultiMap (_, _, map)) key = Map.member key map
notMember key = not . member key
(!) :: Ord k => MultiMap k a -> k -> [a]
(!) = flip lookup
lookup :: Ord k => k -> MultiMap k a -> [a]
lookup key (MultiMap (_, _, map)) = maybe [] id (Map.lookup key map)
empty :: MultiMap k a
empty = MultiMap (0, 0, Map.empty)
insert :: Ord k => k -> a -> MultiMap k a -> MultiMap k a
insert k v (MultiMap (nk, nv, map))
| Map.member k map = MultiMap (nk, succ nv, Map.insert k (v : map Map.! k) map)
| otherwise = MultiMap (succ nk, succ nv, Map.insert k [v] map)
delete :: Ord k => k -> MultiMap k a -> MultiMap k a
delete k m@(MultiMap (nk, nv, map)) = case Map.lookup k map of
Just v -> MultiMap (pred nk, nv fromIntegral (length v), Map.delete k map)
_ -> m
map :: (a -> b) -> MultiMap k a -> MultiMap k b
map f (MultiMap (nk, nv, map)) = MultiMap (nk, nv, Map.map (P.map f) map)
mapKeys :: Ord k2 => (k1 -> k2) -> MultiMap k1 a -> MultiMap k2 a
mapKeys f (MultiMap (nk, nv, map)) = MultiMap (nk, nv, Map.mapKeys f map)
mapWithKey :: (k -> a -> b) -> MultiMap k a -> MultiMap k b
mapWithKey f (MultiMap (nk, nv, map))
= MultiMap (nk, nv, Map.mapWithKey (\k -> P.map (f k)) map)
foldr :: (a -> b -> b) -> b -> MultiMap k a -> b
foldr f e = P.foldr f e . concat . elems
foldl :: (a -> b -> a) -> a -> MultiMap k b -> a
foldl f e = P.foldl f e . concat . elems
foldrWithKey :: (k -> a -> b -> b) -> b -> MultiMap k a -> b
foldrWithKey f e = P.foldr (uncurry f) e . toList
foldlWithKey :: (a -> k -> b -> a) -> a -> MultiMap k b -> a
foldlWithKey f e = P.foldl (\a (k,v) -> f a k v) e . toList
elems :: MultiMap k a -> [[a]]
elems (MultiMap (_, _, map)) = Map.elems map
keys :: MultiMap k a -> [k]
keys (MultiMap (_, _, map)) = Map.keys map
keysSet :: MultiMap k a -> Set k
keysSet (MultiMap (_, _, map)) = Map.keysSet map
assocs :: MultiMap k a -> [(k, [a])]
assocs (MultiMap (_, _, map)) = Map.assocs map
toMap :: MultiMap k a -> Map k [a]
toMap (MultiMap (_, _, theUnderlyingMap)) = theUnderlyingMap
toMapOfSets :: Ord a => MultiMap k a -> Map k (Set a)
toMapOfSets (MultiMap (_, _, map)) = Map.map Set.fromList map
toList :: MultiMap k a -> [(k, a)]
toList (MultiMap (_, _, map))
= concat $ Map.elems $ Map.mapWithKey (\k -> zip (repeat k)) map
fromList :: Ord k => [(k, a)] -> MultiMap k a
fromList = P.foldr (uncurry insert) empty
fromMap :: Map k [a] -> MultiMap k a
fromMap map = MultiMap (numKeys, numValues, map)
where
numKeys = fromIntegral $ Map.size map
numValues = fromIntegral $ Map.foldr (\v s -> length v + s) 0 map
findMin :: MultiMap k a -> Maybe k
findMin (MultiMap (_, _, map))
| Map.null map = Nothing
| otherwise = Just $ fst $ Map.findMin map
findMax :: MultiMap k a -> Maybe k
findMax (MultiMap (_, _, map))
| Map.null map = Nothing
| otherwise = Just $ fst $ Map.findMax map
findMinWithValues :: MultiMap k a -> Maybe (k, [a])
findMinWithValues (MultiMap (_, _, map))
| Map.null map = Nothing
| otherwise = Just $ Map.findMin map
findMaxWithValues :: MultiMap k a -> Maybe (k, [a])
findMaxWithValues (MultiMap (_, _, map))
| Map.null map = Nothing
| otherwise = Just $ Map.findMax map