module Data.Map.IMap
( IMap
, IsMap
, fromList
, intersectionWith
, mapmap
, Key
) where
import qualified Data.Map as M
import qualified Data.IntMap as IM
newtype IMap m v = IMap (Either v (m v))
deriving (Show, Eq)
class IsMap m where
type Key m
fromList :: [(Key m, v)] -> m v
intersectionWith :: (a -> b -> c) -> m a -> m b -> m c
mapmap :: (a -> b) -> m a -> m b
instance Ord k => IsMap (M.Map k) where
type Key (M.Map k) = k
fromList = M.fromList
intersectionWith = M.intersectionWith
mapmap = M.map
instance IsMap IM.IntMap where
type Key IM.IntMap = IM.Key
fromList = IM.fromList
intersectionWith = IM.intersectionWith
mapmap = IM.map
instance IsMap m => IsMap (IMap m) where
type Key (IMap m) = Key m
fromList l = IMap (Right $ fromList l)
intersectionWith f (IMap (Left u)) (IMap (Left v)) = IMap (Left $ f u v)
intersectionWith f (IMap (Left u)) (IMap (Right b)) = IMap (Right $ mapmap ( f u) b)
intersectionWith f (IMap (Right a)) (IMap (Left v)) = IMap (Right $ mapmap (flip f v) a)
intersectionWith f (IMap (Right a)) (IMap (Right b)) = IMap (Right $ intersectionWith f a b)
mapmap f (IMap (Left v)) = IMap (Left $ f v)
mapmap f (IMap (Right a)) = IMap (Right $ mapmap f a)
instance IsMap m => Functor (IMap m) where
fmap = mapmap
instance IsMap m => Applicative (IMap m) where
pure v = IMap (Left v)
(<*>) = intersectionWith ($)