module Haskus.Utils.MultiState
( MStateT
, MState
, mSet
, mGet
, mTryGet
, mModify
, mModify'
, mWith
, runMState
, evalMState
, execMState
, liftMStateT
, (>~:>)
, (>:>)
)
where
import Control.Monad.State.Lazy
import Control.Monad.Identity
import Haskus.Utils.HArray
type MStateT (s :: [*]) m a = StateT (HArray s) m a
type MState (s :: [*]) a = MStateT s Identity a
runMState :: MState s a -> HArray s -> (a,HArray s)
runMState act s = runIdentity (runStateT act s)
evalMState :: MState s a -> HArray s -> a
evalMState act s = runIdentity (evalStateT act s)
execMState :: MState s a -> HArray s -> HArray s
execMState act s = runIdentity (execStateT act s)
mSet :: (Monad m, HArrayIndexT a s) => a -> MStateT s m ()
mSet = modify' . setHArrayT
mGet :: (Monad m, HArrayIndexT a s) => MStateT s m a
mGet = getHArrayT <$> get
mTryGet :: (Monad m, HArrayTryIndexT a s) => MStateT s m (Maybe a)
mTryGet = tryGetHArrayT <$> get
mModify :: (Monad m, HArrayIndexT a s) => (a -> a) -> MStateT s m ()
mModify f = modify (\s -> setHArrayT (f (getHArrayT s)) s)
mModify' :: (Monad m, HArrayIndexT a s) => (a -> a) -> MStateT s m ()
mModify' f = modify' (\s -> setHArrayT (f (getHArrayT s)) s)
mWith :: forall s a m b.
( Monad m
) => a -> MStateT (a ': s) m b -> MStateT s m b
mWith v act = do
s <- get
(r,s') <- lift $ runStateT act (prependHArray v s)
put (tailHArray s')
return r
liftMStateT :: (Monad m) => MStateT xs m x -> HArrayT m xs (x ': xs)
liftMStateT act = HArrayT $ \xs -> do
(x,xs') <- runStateT act xs
return (prependHArray x xs')
(>~:>) :: (Monad m) => HArrayT m xs ys -> MStateT ys m y -> HArrayT m xs (y ': ys)
(>~:>) f g = f >~:~> liftMStateT g
(>:>) :: (Monad m) => MStateT xs m x -> MStateT (x ': xs) m y -> HArrayT m xs (y ': x ': xs)
(>:>) f g = liftMStateT f >~:~> liftMStateT g