A more intuitive approach to the State Monad in Scala

The 'Functional programming in Scala' book (aka 'the red book') defines a state transformation as a function with this signature:

S => (S, A)

where S is a type representing the state of our application and A is the type of the output we get running the transformation. So for the state to advance we would run this transformation function over an initial state to get the new state. There is also a 'State Monad' (SM) that allows to sequence these state transformations.

Unfortunately that signature does not really match the intuition of many programmers. When thinking about state transformations we usually imagine there will be a current state and an input, and that will bring us to the next state and an output. So if the input is of type I then we would expect state transitions to be defined by this signature instead:

(S, I) => (S, A)

And then we would define a state machine as a function like this:

def transformation(s: S, i: I): (S, A) =
  (s, i) match
    case ...

So a programmer can be a bit confused as the signature of the state transition expected differs from the one used by the State Monad. But the solution is actually simple! Note that the signature (S, I) => (S, A) is similar to:

I => S => (S, A)

So we only need to reshape our function so for each input we would return a state transformation function:

def transformation(i: I): S => (S, A) = s =>
  (s, i) match // We can process state as a (S, I) => ... function
    case ...
    case ...

And that's pretty much all! Now we can use the State Monad alongside our traditional understanding of state transitions.

0
Subscribe to my newsletter

Read articles from Luis Rodero-Merino directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Luis Rodero-Merino
Luis Rodero-Merino

Dev interested in functional programming solutions for Scala.