Changes to use a MonadState constraint.

This allows a bit more flexibility while experimenting with
different ways of tying together the monad transformer stack.

It also means that we can limit the effects that our helper
functions have access to - if they don't need to access the state,
we don't provide the MonadState constraint, and then we have something
that we can reuse in other monad transformer stacks later on.