Skip to content
State Monad
step 1/4

Reading — step 1 of 4

Learn

~2 min readBeyond Functor

The State monad threads a state value through a sequence of operations — pure code that LOOKS like it has mutable state.

import Control.Monad.State

-- State Int Int = a function: Int -> (Int, Int)
-- (the new state, the result)

counter :: State Int Int
counter = do
    n <- get          -- read state
    put (n + 1)        -- write state
    return n           -- yield current value

-- Use:
runState counter 0    -- (0, 1)  — first value 0, new state 1

runState (do
    a <- counter
    b <- counter
    c <- counter
    return [a, b, c]
) 0
-- ([0, 1, 2], 3)  — three counts, ending state 3

Key operations:

  • get :: State s s — read current state
  • put :: s -> State s () — replace state
  • modify :: (s -> s) -> State s () — apply function
  • gets :: (s -> a) -> State s a — read transformed
  • runState :: State s a -> s -> (a, s) — extract
  • evalState :: State s a -> s -> a — just the result
  • execState :: State s a -> s -> s — just the final state

Real example — labeling a tree:

data Tree a = Leaf | Node (Tree a) a (Tree a)

label :: Tree a -> Tree (Int, a)
label t = evalState (label' t) 0
  where
    label' Leaf = return Leaf
    label' (Node l x r) = do
        l' <- label' l
        n <- get
        put (n + 1)
        r' <- label' r
        return (Node l' (n, x) r')

Cleaner than threading the counter manually through every recursive call.

State is StateT Identity — the State monad transformer over Identity. In real code you usually use StateT s IO (state + IO) or StateT s Maybe.

Why useful in pure code:

  • Tracking unique IDs across a recursive computation
  • Building up a result while consuming an iterator
  • Algorithms that need a running register (parser state, evaluator)

Performance note: pure State copies state on every modification. For high-throughput use STRef (in the ST monad) or IORef (in IO).

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…