Enter the Lambda
Jump to navigation
Jump to search
Do not try to change the state; that's impossible. Instead only try to realize the truth: There is no state.
-- ---------------------------------------------------------------------------
-- | A parameterizable state monad where /s/ is the type of the state
-- to carry and /a/ is the type of the /return value/.
newtype State s a = State { runState :: s -> (a, s) }
-- |Evaluate this state monad with the given initial state,throwing
-- away the final state. Very much like @fst@ composed with
-- @runstate@.
evalState :: State s a -- ^The state to evaluate
-> s -- ^An initial value
-> a -- ^The return value of the state application
evalState m s = fst (runState m s)
-- |Execute this state and return the new state, throwing away the
-- return value. Very much like @snd@ composed with
-- @runstate@.
execState :: State s a -- ^The state to evaluate
-> s -- ^An initial value
-> s -- ^The new state
execState m s = snd (runState m s)
-- |Map a stateful computation from one (return value, state) pair to
-- another. For instance, to convert numberTree from a function that
-- returns a tree to a function that returns the sum of the numbered
-- tree (see the Examples section for numberTree and sumTree) you may
-- write:
--
-- > sumNumberedTree :: (Eq a) => Tree a -> State (Table a) Int
-- > sumNumberedTree = mapState (\ (t, tab) -> (sumTree t, tab)) . numberTree
mapState :: ((a, s) -> (b, s)) -> State s a -> State s b
mapState f m = State $ f . runState m
-- |Apply this function to this state and return the resulting state.
withState :: (s -> s) -> State s a -> State s a
withState f m = State $ runState m . f
instance Functor (State s) where
fmap f m = State $ \s -> let
(a, s') = runState m s
in (f a, s')
instance Monad (State s) where
return a = State $ \s -> (a, s)
m >>= k = State $ \s -> let
(a, s') = runState m s
in runState (k a) s'
instance MonadFix (State s) where
mfix f = State $ \s -> let (a, s') = runState (f a) s in (a, s')
instance MonadState s (State s) where
get = State $ \s -> (s, s)
put s = State $ \_ -> ((), s)