module Data.TrieMap.MultiRec.IMap where
import Data.TrieMap.MultiRec.Class
import Data.TrieMap.MultiRec.Sized
import Data.TrieMap.TrieKey
import Control.Applicative
import Control.Arrow
import Generics.MultiRec
newtype IMap phi xi r a ix = IMap (HTrieMap phi r (I ix a) xi)
type instance HTrieMapT phi (I xi) = IMap phi xi
type instance HTrieMap phi (I xi r) = HTrieMapT phi (I xi) r
combineI :: (I xi r ix -> a ix -> b ix -> Maybe (c ix)) -> r xi -> I ix a xi -> I ix b xi -> Maybe (I ix c xi)
combineI f k (I a) (I b) = I <$> f (I k) a b
mapI :: Functor f => (I xi r ix -> a ix -> f (b ix)) -> r xi -> I ix a xi -> f (I ix b xi)
mapI f k (I a) = I <$> f (I k) a
sizeI :: HSized phi r -> HSized phi (I xi r)
sizeI s (I x) = s x
instance El phi xi => HTrieKeyT phi (I xi) (IMap phi xi) where
emptyT _ = IMap (emptyH proof)
nullT _ (IMap m) = nullH proof m
sizeT s (IMap m) = sizeH (sizeI s) m
lookupT _ (I k) (IMap m) = unI <$> lookupH proof k m
lookupIxT _ s (I k) (IMap m) = fmap unI <$> lookupIxH proof (sizeI s) k m
assocAtT _ s i (IMap m) = case assocAtH proof (sizeI s) i m of
(i, k, I a) -> (i, I k, a)
updateAtT _ s f i (IMap m) = IMap (updateAtH proof (sizeI s) (\ i' k (I a) -> I <$> f i' (I k) a) i m)
alterT _ s f (I k) (IMap m) = IMap (alterH proof (sizeI s) f' k m) where
f' = fmap I . f . fmap unI
traverseWithKeyT _ s f (IMap m) = IMap <$> traverseWithKeyH proof (sizeI s) (mapI f) m
foldWithKeyT _ f (IMap m) = foldWithKeyH proof (\ k (I a) -> f (I k) a) m
foldlWithKeyT _ f (IMap m) = foldlWithKeyH proof (\ k z (I a) -> f (I k) z a) m
mapEitherT _ s1 s2 f (IMap m) = (IMap *** IMap) (mapEitherH proof (sizeI s1) (sizeI s2) f' m) where
f' k (I a) = (fmap I *** fmap I) (f (I k) a)
splitLookupT pf s f (I k) (IMap m) = IMap `sides` splitLookupH proof (sizeI s) f' k m
where f' = sides (I <$>) . f . unI
unionT pf s f (IMap m1) (IMap m2) = IMap (unionH proof (sizeI s) (combineI f) m1 m2)
isectT pf s f (IMap m1) (IMap m2) = IMap (isectH proof (sizeI s) (combineI f) m1 m2)
diffT pf s f (IMap m1) (IMap m2) = IMap (diffH proof (sizeI s) (combineI f) m1 m2)
extractMinT pf s (IMap m) = do
((k, I a), m') <- extractMinH proof (sizeI s) m
return ((I k, a), IMap m')
extractMaxT pf s (IMap m) = do
((k, I a), m') <- extractMaxH proof (sizeI s) m
return ((I k, a), IMap m')
alterMinT pf s f (IMap m) = IMap (alterMinH proof (sizeI s) (mapI f) m)
alterMaxT pf s f (IMap m) = IMap (alterMaxH proof (sizeI s) (mapI f) m)
isSubmapT pf (<=) (IMap m1) (IMap m2) = isSubmapH proof (<<=) m1 m2 where
I a <<= I b = a <= b
fromListT _ s f xs = IMap (fromListH proof (sizeI s) (\ k (I a) (I b) -> I (f (I k) a b)) [(k, I a) | (I k, a) <- xs])
fromAscListT _ s f xs = IMap (fromAscListH proof (sizeI s) (\ k (I a) (I b) -> I (f (I k) a b)) [(k, I a) | (I k, a) <- xs])
fromDistAscListT _ s xs = IMap (fromDistAscListH proof (sizeI s) [(k, I a) | (I k, a) <- xs])
instance (El phi xi, HTrieKey phi r (HTrieMap phi r)) => HTrieKey phi (I xi r) (IMap phi xi r) where
emptyH = emptyT
nullH = nullT
sizeH = sizeT
lookupH = lookupT
lookupIxH = lookupIxT
assocAtH = assocAtT
updateAtH = updateAtT
alterH = alterT
traverseWithKeyH = traverseWithKeyT
foldWithKeyH = foldWithKeyT
foldlWithKeyH = foldlWithKeyT
mapEitherH = mapEitherT
splitLookupH = splitLookupT
unionH = unionT
isectH = isectT
diffH = diffT
alterMinH = alterMinT
alterMaxH = alterMaxT
extractMinH = extractMinT
extractMaxH = extractMaxT
isSubmapH = isSubmapT
fromListH = fromListT
fromAscListH = fromAscListT
fromDistAscListH = fromDistAscListT