-- A state monad transformer -- by Campbell Taylor 3/2008 module StateT where import Monad data StateT state m value = StateT { stateRunner :: state -> m (value, state) } runStateT :: Monad m => StateT state m value -> state -> m (value, state) runStateT action initialState = (stateRunner action) initialState evalStateT :: Monad m => StateT state m value -> state -> m value evalStateT action initialState = do (value, _finalState) <- runStateT action initialState return value execStateT :: Monad m => StateT state m value -> state -> m state execStateT action initialState = do (_value, finalState) <- runStateT action initialState return finalState instance Monad m => Monad (StateT state m) where return value = StateT (\ state -> return (value, state)) action >>= extender = StateT (\ firstState -> do (intermediateValue, secondState) <- runStateT action firstState runStateT (extender intermediateValue) secondState) fail message = StateT (\ _state -> fail message) get :: Monad m => StateT state m state get = StateT (\ state -> return (state, state)) put :: Monad m => state -> StateT state m () put newState = StateT (\ _oldState -> return ((), newState)) instance (Monad m, MonadPlus m) => MonadPlus (StateT state m) where mzero = StateT (\ _state -> mzero) a `mplus` b = StateT (\ state -> runStateT a state `mplus` runStateT b state)