module Control.Monad.Trans.State.Strict (
State,
state,
runState,
evalState,
execState,
mapState,
withState,
StateT(..),
evalStateT,
execStateT,
mapStateT,
withStateT,
get,
put,
modify,
gets,
liftCallCC,
liftCallCC',
liftCatch,
liftListen,
liftPass,
) where
import Control.Monad.IO.Class
import Control.Monad.Trans.Class
import Data.Functor.Identity
import Control.Applicative
import Control.Monad
import Control.Monad.Fix
type State s = StateT s Identity
state :: Monad m
=> (s -> (a, s))
-> StateT s m a
state f = StateT (return . f)
runState :: State s a
-> s
-> (a, s)
runState m = runIdentity . runStateT m
evalState :: State s a
-> s
-> a
evalState m s = fst (runState m s)
execState :: State s a
-> s
-> s
execState m s = snd (runState m s)
mapState :: ((a, s) -> (b, s)) -> State s a -> State s b
mapState f = mapStateT (Identity . f . runIdentity)
withState :: (s -> s) -> State s a -> State s a
withState = withStateT
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 = return
(<*>) = ap
instance (Functor m, MonadPlus m) => Alternative (StateT s m) where
empty = mzero
(<|>) = mplus
instance (Monad m) => Monad (StateT s m) where
return a = state $ \s -> (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
instance MonadTrans (StateT s) where
lift m = StateT $ \s -> do
a <- m
return (a, s)
instance (MonadIO m) => MonadIO (StateT s m) where
liftIO = lift . liftIO
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)
gets :: (Monad m) => (s -> a) -> StateT s m a
gets f = state $ \s -> (f s, s)
liftCallCC :: ((((a,s) -> m (b,s)) -> m (a,s)) -> m (a,s)) ->
((a -> StateT s m b) -> StateT s m a) -> StateT s m a
liftCallCC callCC f = StateT $ \s ->
callCC $ \c ->
runStateT (f (\a -> StateT $ \ _ -> c (a, s))) s
liftCallCC' :: ((((a,s) -> m (b,s)) -> m (a,s)) -> m (a,s)) ->
((a -> StateT s m b) -> StateT s m a) -> StateT s m a
liftCallCC' callCC f = StateT $ \s ->
callCC $ \c ->
runStateT (f (\a -> StateT $ \s' -> c (a, s'))) s
liftCatch :: (m (a,s) -> (e -> m (a,s)) -> m (a,s)) ->
StateT s m a -> (e -> StateT s m a) -> StateT s m a
liftCatch catchError m h =
StateT $ \s -> runStateT m s `catchError` \e -> runStateT (h e) s
liftListen :: Monad m =>
(m (a,s) -> m ((a,s),w)) -> StateT s m a -> StateT s m (a,w)
liftListen listen m = StateT $ \s -> do
((a, s'), w) <- listen (runStateT m s)
return ((a, w), s')
liftPass :: Monad m =>
(m ((a,s),b) -> m (a,s)) -> StateT s m (a,b) -> StateT s m a
liftPass pass m = StateT $ \s -> pass $ do
((a, f), s') <- runStateT m s
return ((a, s'), f)