module IdeSession.Strict.StateT (
StrictStateT(..)
, modify
, evalStateT
, execStateT
, StrictState
, runState
, evalState
, execState
) where
import Control.Applicative
import Control.Monad.State.Class
import Control.Monad.Trans.Class
import Data.Functor.Identity
newtype StrictStateT s m a = StrictStateT { runStateT :: s -> m (a, s) }
instance Monad m => Applicative (StrictStateT s m) where
pure = return
f <*> x = do f' <- f ; x' <- x ; return (f' x')
instance Monad m => Monad (StrictStateT s m) where
return a = StrictStateT $ \s -> return (a, s)
x >>= f = StrictStateT $ \s -> do (a, s') <- runStateT x s
(b, s'') <- runStateT (f a) s'
return (b, s'')
instance Monad m => Functor (StrictStateT s m) where
f `fmap` m = m >>= return . f
instance Monad m => MonadState s (StrictStateT s m) where
get = StrictStateT $ \s -> return (s, s)
put s = StrictStateT $ \_ -> s `seq` return ((), s)
state f = StrictStateT $ \s -> do let (a, s') = f s
s' `seq` return (a, s')
instance MonadTrans (StrictStateT s) where
lift m = StrictStateT $ \s -> do a <- m
return (a, s)
evalStateT :: Monad m => StrictStateT s m a -> s -> m a
evalStateT m s = do (a, _) <- runStateT m s ; return a
execStateT :: Monad m => StrictStateT s m a -> s -> m s
execStateT m s = do (_, s') <- runStateT m s ; return s'
type StrictState s = StrictStateT s Identity
runState :: StrictState s a -> s -> (a, s)
runState m s = runIdentity $ runStateT m s
evalState :: StrictState s a -> s -> a
evalState m = fst . runState m
execState :: StrictState s a -> s -> s
execState m = snd . runState m