🎓 A1Learner
🔍
0 of 50 lessons completed

Haskell StateT

StateT adds a changeable value to a monad. Each step can read the value and replace it with a new one.

Get and put change the state

The block reads 41, stores 42, and returns the old value. The printed pair shows both numbers.

import Control.Monad.Trans.State
import Data.Functor.Identity
main :: IO ()
main = print (runIdentity (runStateT (do n <- get; put (n + 1); return n) 41))

Modify changes the state with a function

The block adds 10 to a starting state of 5. Both the result and the final state are 15.

import Control.Monad.Trans.State
import Data.Functor.Identity
main :: IO ()
main = print (runIdentity (runStateT (do modify (+10); n <- get; return n) 5))

StateT can sit over IO

StateT can layer its state over IO. The block returns 100 and moves the state to 105.

import Control.Monad.Trans.State
main :: IO ()
main = do
  (result, final) <- runStateT (do n <- get; put (n + 5); return n) 100
  print result
  print final

Example

import Control.Monad.Trans.State
main :: IO ()
main = do
  (result, final) <- runStateT (do n <- get; put (n + 5); m <- get; put (m * 2); return m) 10
  print result
  print final

Key points

  • StateT: a transformer that carries a changeable value.
  • Use get to read the current state inside a StateT block.
  • Use put to replace the state with a new value.
  • Use modify to change the state with a function.
  • Use runStateT to run a StateT block with an initial state.

In this example, the first step moves the state from 10 to 15, the second step doubles 15 to 30, and the block returns 15 while the final state is 30.

Note

the result comes first and the final state second in the pair from runStateT.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Haskell Playground

Exercise

What does runStateT return?