module Control.Monad.Trans.State.Strict (
StateT(..),
evalStateT,
execStateT,
mapStateT,
withStateT,
get,
put,
modify,
modify',
gets
) where
import Control.Applicative
import Control.Monad
import Control.Monad.Fix
state :: (Monad m)
=> (s -> (a, s))
-> StateT s m a
state f = StateT (return . f)
newtype StateT s m a = StateT { runStateT :: s -> m (a,s) }
evalStateT :: (Monad m) => StateT s m a -> s -> m a
evalStateT m s = do
(a, _) <- runStateT m s
return a
execStateT :: (Monad m) => StateT s m a -> s -> m s
execStateT m s = do
(_, s') <- runStateT m s
return s'
mapStateT :: (m (a, s) -> n (b, s)) -> StateT s m a -> StateT s n b
mapStateT f m = StateT $ f . runStateT m
withStateT :: (s -> s) -> StateT s m a -> StateT s m a
withStateT f m = StateT $ runStateT m . f
instance (Functor m) => Functor (StateT s m) where
fmap f m = StateT $ \ s ->
fmap (\ (a, s') -> (f a, s')) $ runStateT m s
instance (Functor m, Monad m) => Applicative (StateT s m) where
pure a = StateT $ \ s -> return (a, s)
StateT mf <*> StateT mx = StateT $ \ s -> do
(f, s') <- mf s
(x, s'') <- mx s'
return (f x, s'')
instance (Functor m, MonadPlus m) => Alternative (StateT s m) where
empty = StateT $ \ _ -> mzero
StateT m <|> StateT n = StateT $ \ s -> m s `mplus` n s
instance (Monad m) => Monad (StateT s m) where
return a = StateT $ \ s -> return (a, s)
m >>= k = StateT $ \ s -> do
(a, s') <- runStateT m s
runStateT (k a) s'
fail str = StateT $ \ _ -> fail str
instance (MonadPlus m) => MonadPlus (StateT s m) where
mzero = StateT $ \ _ -> mzero
m `mplus` n = StateT $ \ s -> runStateT m s `mplus` runStateT n s
instance (MonadFix m) => MonadFix (StateT s m) where
mfix f = StateT $ \ s -> mfix $ \ ~(a, _) -> runStateT (f a) s
get :: (Monad m) => StateT s m s
get = state $ \ s -> (s, s)
put :: (Monad m) => s -> StateT s m ()
put s = state $ \ _ -> ((), s)
modify :: (Monad m) => (s -> s) -> StateT s m ()
modify f = state $ \ s -> ((), f s)
modify' :: (Monad m) => (s -> s) -> StateT s m ()
modify' f = do
s <- get
put $! f s
gets :: (Monad m) => (s -> a) -> StateT s m a
gets f = state $ \ s -> (f s, s)