[Haskell-cafe] state monad transformer that adds or combines state

Alexis King lexi.lambda at gmail.com
Tue May 15 21:55:00 UTC 2018

> On May 15, 2018, at 16:29, Dennis Raddle <dennis.raddle at gmail.com>
> wrote:
> I'm not sure what happens if I apply a StateT to an existing State or
> StateT monad. Not sure how 'get' and 'put' would function, or if I
> would need to lift get and put to choose which state to access.

The immediate answer to this question is “yes”. If you had StateT on top
of StateT, you could access the different pieces of state by lifting to
the appropriate level. As Ryan points out, this is admittedly a bit
awkward, since it doesn’t work with the classes from mtl (due to the
functional dependency on MonadState). Still, it’s possible.

Extensible effects can solve this a little more cleanly. You can easily
handle an effect locally, and you can have multiple state effects with
different types. For example, using freer-simple:

  import Control.Monad.Freer
  import Control.Monad.Freer.State

  f :: Member (State StdGen) eff => Eff eff Double
  f = do
    r <- <do something pseudorandomly>
    r2 <- runState @Int 3 (deeperFunc r)

  deeperFunc :: Members '[State StdGen, State Int] eff
             => Double -> Eff eff Double
  deeperFunc = <...>

This works just fine.

To others suggesting the OP make the state a product: this seems
unsatisfactory to me. It means you have to carry around the state for
every local computation you might use, even long after it is no longer
needed. If the state is truly local, there’s really no need to carry it
around after its lifetime is, semantically, over. We invented local
variables for a reason. (Such globalization of state also won’t work in
general for things like recursive functions, for the same reasons that
local variables cannot be properly implemented without a stack.)

One small disclaimer: I am the maintainer of freer-simple, though I
can’t really claim to be the author, since it’s a fork, and others did
the vast majority of the work. Take my bias as you will.


More information about the Haskell-Cafe mailing list