We discovered earlier in this chapter that Parse from Chapter 10 was a monad. It has two logically distinct aspects. One is the idea of a parse failing and providing a message with the details (we represented this using the Either type). The other involves carrying around a piece of implicit state, in our case, the partially consumed ByteString.

This need for a way to read and write
state is common enough in Haskell programs that the standard libraries
provide a monad named State that is dedicated to this
purpose. This monad lives in the `Control.Monad.State`

module.

Where our Parse type carried
around a ByteString as its piece of state, the
State monad can carry any type of state. We’ll refer to the
state’s unknown type as `s`

.

What’s an obvious and general thing we
might want to do with a state? Given a state value, we inspect it, and
then produce a result and a new state value. Let’s say the result can be
of any type `a`

. A type signature that
captures this idea is s -> (a, s). Take a state `s`

, do something with it, and return a result
`a`

and possibly a new state `s`

.

Let’s develop some simple code that’s
*almost* the State monad, and then
take a look at the real thing. We’ll start with our type definition,
which has exactly the obvious type that we just described:

-- file: ch14/SimpleState.hs type SimpleState s a = s -> (a, s)

Our monad is a function that transforms
one state into another, yielding a result when it does so. Because of
this, the `State`

monad ...

Start Free Trial

No credit card required