A Generic State Transformer
Since state is a handy thing to have, the standard library includes a module Control.Monad.State
that defines a parameterized version of the state-transformer monad. This file is a simplified version of that library.
We will only allow clients to use the functions declared below.
The type definition for a generic state transformer is very simple:
It is a parameterized state-transformer monad where the state is denoted by type s
and the return value of the transformer is the type a
. We make the above a monad by declaring it to be an instance of the monad
typeclass
> instance Monad (State s) where
> return x = S (\s -> (x, s))
> st >>= f = S (\s -> let (x, s') = runState st s
> in runState (f x) s')
where the function runState
(called apply
in the lecture) is just
There are also two other was of evaluating the state monad. The first only returns the final result,
and the second only returns the final state.
Accessing and Modifying State
Since our notion of state is generic, it is useful to write a get
and put
function with which one can access and modify the state. We can easily get
the current state via
That is, get
denotes an action that leaves the state unchanged, but returns the state itself as a value. Note that although get does not have a function type (unless you peek under the covers of State), we consider it a monadic "action".
Dually, to modify the state to some new value s'
we can write the function
which denotes an action that ignores (ie blows away) the old state and replaces it with s
. Note that the put s
is an action that itself yields nothing (that is, merely the unit value.)