module StateMonad (applyStateMonad,
readState, writeState, writeState_, innerMonad) where
import Control.Monad.State
type StateMonad s a = State s a
{-
newtype StateMonad s a = SM (s -> (s, a))
instance Monad (StateMonad s) where
(SM x) >>= f = SM $ \s -> let (s', v) = x s
(SM y) = f v
in y s'
return a = SM $ \s -> (s, a)
-}
{- apply the state monad to a state to give a return value and new state -}
applyStateMonad :: StateMonad s a -> s -> (s, a)
applyStateMonad m x = (b,a)
where (a,b) = runState m x
{- get the state from a monad -}
getState :: StateMonad s s
getState = get
{- set the state in the monad -}
setState :: s -> StateMonad s ()
setState = put
{- read the state -}
readState :: (s -> a) -> StateMonad s a
readState f = do s <- getState
return (f s)
{- write the state and return a value -}
writeState :: (s -> (s,a)) -> StateMonad s a
writeState f = do s <- getState
let (s',a) = f s
setState s'
return a
{- write the state without returning a value -}
writeState_ :: (s -> s) -> StateMonad s ()
writeState_ f = writeState (\s -> (f s, ()))
{- convert a state monad that changes it's output state to one that doesn't -}
innerMonad :: StateMonad s a -> StateMonad s (s, a)
innerMonad m = State $ \s -> let r = applyStateMonad m s
in (r, s)
|