module Data.TrieMap.ReverseMap (reverse, unreverse) where
import Data.TrieMap.TrieKey
import Data.TrieMap.Modifiers
import Data.TrieMap.Applicative
import Control.Applicative
import Prelude hiding (reverse)
import qualified Data.List as L
instance TrieKey k => TrieKey (Rev k) where
newtype TrieMap (Rev k) a = RMap (TrieMap k a)
emptyM = RMap emptyM
singletonM s (Rev k) a = RMap (singletonM s k a)
nullM (RMap m) = nullM m
sizeM s (RMap m) = sizeM s m
lookupM (Rev k) (RMap m) = lookupM k m
traverseWithKeyM s f (RMap m) = RMap <$> runDual (traverseWithKeyM s (\ k a -> Dual (f (Rev k) a)) m)
alterM s f (Rev k) (RMap m) = RMap (alterM s f k m)
alterLookupM s f (Rev k) (RMap m) = onUnboxed RMap (alterLookupM s f k) m
splitLookupM s f (Rev k) (RMap m) = sides RMap (splitLookupM s f' k) m
where f' x = case f x of
(# xL, ans, xR #) -> (# xR, ans, xL #)
mapMaybeM s f (RMap m) = RMap (mapMaybeM s (f . Rev) m)
mapEitherM s1 s2 f (RMap m) = both RMap RMap (mapEitherM s1 s2 (f . Rev)) m
foldWithKeyM f (RMap m) = foldlWithKeyM (flip . f . Rev) m
foldlWithKeyM f (RMap m) = foldWithKeyM (flip . f . Rev) m
unionM s f (RMap m1) (RMap m2) = RMap (unionM s (f . Rev) m1 m2)
isectM s f (RMap m1) (RMap m2) = RMap (isectM s (f . Rev) m1 m2)
diffM s f (RMap m1) (RMap m2) = RMap (diffM s (f . Rev) m1 m2)
extractM s f (RMap m) = fmap RMap <$> runDual (extractM s (\ k a -> Dual (f (Rev k) a)) m)
isSubmapM (<=) (RMap m1) (RMap m2) = isSubmapM (<=) m1 m2
fromListM s f xs = RMap (fromListM s (f . Rev) [(k, a) | (Rev k, a) <- xs])
fromAscListM s f xs = RMap (fromAscListM s (\ k -> flip (f (Rev k))) [(k, a) | (Rev k, a) <- L.reverse xs])
fromDistAscListM s xs = RMap (fromDistAscListM s [(k, a) | (Rev k, a) <- L.reverse xs])
reverse :: TrieMap k a -> TrieMap (Rev k) a
reverse = RMap
unreverse :: TrieMap (Rev k) a -> TrieMap k a
unreverse (RMap m) = m