Dec 30, 2015

HANDLING state in a monadic way is one of the techniques Haskellers
come to learn about. But how does it work, roughly?

The following is a simplified, intuitional explanation of the state
monad. It's basically a trick of function currying. Suppose you have
some program state, and some functions that do something to your program
state:

You can take advantage of the associativity of the function arrow and
think of the function types as Int ->
(MyState -> MyState). Now, this
return type is a transformation from an initial state to a final state.
If we alias the type: typeStateWrapper =
MyState -> MyState, we can write our
function types as Int ->
StateWrapper.

So, the new function types are:

increaseState, decreaseState :: Int -> StateWrapper

If we say increaseState 2, we get a result of
type StateWrapper. If we say
decreaseState 1, we get a result also of type
StateWrapper. If we compose these two values
(which are actually functions, remember), we get a final value of type
StateWrapper, that is
MyState -> MyState. In fact, no
matter how many stateful operations we do, if we compose them all in
sequence, we get a final function of MyState ->
MyState.

At the end of the sequencing (the composition), all we have to do is
feed in the initial state, and we get back the final state after
carrying out all the 'stateful' operations.

So, you ask, why the need for a state monad at all? Why not just do
function composition in the first place? The answer is that the state
wrapper type is slightly more complicated than what we've seen above. In
reality, it's closer to typeStateWrapper s a
= s -> (a, s), that is,
given an initial state s, it returns a result value
a and a final state s. A series
of functions of this type can't be composed together using normal
function composition; and hence we use monadic binding to do the
job.

So monadic binding is a more powerful form of function composition
and hence action sequencing that can handle unruly types (but which
still follow a certain pattern, hence the famous (>>=) :: m
a -> (a -> m b) -> m
b).

To get a more accurate idea of how the state monad works, see Graham
Hutton's excellent tutorial.