module Data.TrieMap.ReverseMap () where
import Control.Applicative
import Control.Monad
import Control.Monad.Ends
import Data.Foldable
import qualified Data.Monoid as M
import Data.TrieMap.TrieKey
import Data.TrieMap.Modifiers
import Data.TrieMap.Sized
import Prelude hiding (foldr, foldl, foldr1, foldl1)
newtype DualPlus m a = DualPlus {runDualPlus :: m a} deriving (Functor, Monad)
newtype Dual f a = Dual {runDual :: f a} deriving (Functor)
instance Applicative f => Applicative (Dual f) where
pure a = Dual (pure a)
Dual f <*> Dual x = Dual (x <**> f)
instance MonadPlus m => MonadPlus (DualPlus m) where
mzero = DualPlus mzero
DualPlus m `mplus` DualPlus k = DualPlus (k `mplus` m)
instance TrieKey k => Foldable (TrieMap (Rev k)) where
foldMap f (RevMap m) = M.getDual (foldMap (M.Dual . f) m)
foldr f z (RevMap m) = foldl (flip f) z m
foldl f z (RevMap m) = foldr (flip f) z m
foldr1 f (RevMap m) = foldl1 (flip f) m
foldl1 f (RevMap m) = foldr1 (flip f) m
instance TrieKey k => TrieKey (Rev k) where
newtype TrieMap (Rev k) a = RevMap (TrieMap k a)
newtype Hole (Rev k) a = RHole (Hole k a)
emptyM = RevMap emptyM
singletonM (Rev k) a = RevMap (singletonM k a)
lookupM (Rev k) (RevMap m) = lookupM k m
sizeM (RevMap m) = sizeM m
getSimpleM (RevMap m) = getSimpleM m
fmapM f (RevMap m) = RevMap (fmapM f m)
traverseM f (RevMap m) = RevMap <$> runDual (traverseM (Dual . f) m)
mapMaybeM f (RevMap m) = RevMap (mapMaybeM f m)
mapEitherM f (RevMap m) = both RevMap RevMap (mapEitherM f) m
unionM f (RevMap m1) (RevMap m2) = RevMap (unionM f m1 m2)
isectM f (RevMap m1) (RevMap m2) = RevMap (isectM f m1 m2)
diffM f (RevMap m1) (RevMap m2) = RevMap (diffM f m1 m2)
isSubmapM (<=) (RevMap m1) (RevMap m2) = isSubmapM (<=) m1 m2
singleHoleM (Rev k) = RHole (singleHoleM k)
beforeM (RHole hole) = RevMap (afterM hole)
beforeWithM a (RHole hole) = RevMap (afterWithM a hole)
afterM (RHole hole) = RevMap (beforeM hole)
afterWithM a (RHole hole) = RevMap (beforeWithM a hole)
searchMC (Rev k) (RevMap m) = mapSearch RHole (searchMC k m)
indexM i (RevMap m) = case indexM (revIndex i m) m of
(# i', a, hole #) -> (# revIndex i' a, a, RHole hole #)
where revIndex :: Sized a => Int -> a -> Int
revIndex i a = getSize a 1 i
extractHoleM (RevMap m) = fmap RHole <$> runDualPlus (extractHoleM m)
firstHoleM (RevMap m) = First (fmap RHole <$> getLast (lastHoleM m))
lastHoleM (RevMap m) = Last (fmap RHole <$> getFirst (firstHoleM m))
assignM v (RHole m) = RevMap (assignM v m)
clearM (RHole m) = RevMap (clearM m)
insertWithM f (Rev k) a (RevMap m) = RevMap (insertWithM f k a m)
fromListM f xs = RevMap (fromListM f [(k, a) | (Rev k, a) <- xs])
fromAscListM f xs = RevMap (fromAscListM (flip f) [(k, a) | (Rev k, a) <- reverse xs])
fromDistAscListM xs = RevMap (fromDistAscListM [(k, a) | (Rev k, a) <- reverse xs])
unifierM (Rev k') (Rev k) a = RHole <$> unifierM k' k a