module Control.Monad.Array.IntMap (IntMapT, evalIntMapT, execIntMapT, execIntMapT_, evalIntMapT_, IntMapM, execIntMapM, evalIntMapM, execIntMapM_, evalIntMapM_) where
import Control.Monad.Array.Class
import Control.Monad.State
import Control.Monad.Reader
import Control.Monad.Writer.Class
import Control.Monad.Trans
import qualified Data.IntMap as IM
import Data.IntMap(IntMap)
import Control.Monad
newtype IntMapT e m a = IntMapT {runIMapT :: ReaderT e (StateT (IntMap e) m) a} deriving (Monad, MonadFix, MonadPlus, MonadIO, MonadWriter w)
newtype IntMapM e a = IntMapM {runIMapM :: ReaderT e (State (IntMap e)) a} deriving (Monad, MonadFix)
evalIntMapT :: Monad m => e -> IntMapT e m a -> m a
evalIntMapT d m = evalStateT (runReaderT (runIMapT m) d) IM.empty
execIntMapT :: Monad m => e -> IntMapT e m a -> m (IntMap e)
execIntMapT d m = execStateT (runReaderT (runIMapT m) d) IM.empty
evalIntMapM :: e -> IntMapM e a -> a
evalIntMapM d m = evalState (runReaderT (runIMapM m) d) IM.empty
execIntMapM :: e -> IntMapM e a -> IntMap e
execIntMapM d m = execState (runReaderT (runIMapM m) d) IM.empty
evalIntMapT_ :: Monad m => IntMapT e m a -> m a
evalIntMapT_ = evalIntMapT emptyElement
execIntMapT_ :: Monad m => IntMapT e m a -> m (IntMap e)
execIntMapT_ = execIntMapT emptyElement
evalIntMapM_ :: IntMapM e a -> a
evalIntMapM_ = evalIntMapM emptyElement
execIntMapM_ :: IntMapM e a -> IntMap e
execIntMapM_ = execIntMapM emptyElement
emptyElement :: e
emptyElement = error "Undefined array element"
instance MonadTrans (IntMapT e) where
lift = IntMapT . lift . lift
instance Monad m => MonadArray (IntMapT e m) where
type ArrayElem (IntMapT e m) = e
readAt i = IntMapT $ gets (IM.lookup i) >>= maybe ask return
writeAt i x = IntMapT $ modify (IM.insert i x)
askSize = IntMapT $ gets IM.size
ensureSize _ = return ()
askElems = IntMapT $ gets IM.elems
askAssocs = IntMapT $ gets IM.toList
instance MonadArray (IntMapM e) where
type ArrayElem (IntMapM e) = e
readAt i = IntMapM $ gets (IM.lookup i) >>= maybe ask return
writeAt i x = IntMapM $ modify (IM.insert i x)
askSize = IntMapM $ gets IM.size
ensureSize _ = return ()
askElems = IntMapM $ gets IM.elems
askAssocs = IntMapM $ gets IM.toList
instance MonadState s m => MonadState s (IntMapT e m) where
get = lift get
put = lift . put
instance MonadReader r m => MonadReader r (IntMapT e m) where
ask = lift ask
local f = (lift . local f . return =<<)