State makes changing state explicit without giving up pure functions. A State[S, A] value is a computation that accepts an initial state S and returns both a result A and the next state: S => (A, S). Rather than mutating hidden memory, it describes the transition for its caller to run and thread onward. section 6.5 section 6.7
A random-number generator exposes the contrast. An imperative generator updates internal state whenever nextInt is called, so a result depends on an unobservable call history. A functional generator instead returns `(n, nextRng)`: the original generator remains unchanged, and the caller explicitly chooses the generator used for the following draw. Given the same initial RNG, the sequence is reproducible. section 6.1 section 6.2
scala> val rng = SimpleRNG(42) #1 val rng: SimpleRNG = SimpleRNG(42) scala> val (n1, rng2) = rng.nextInt #2 val n1: Int = 16159453 val rng2: RNG = SimpleRNG(1059025964525) scala> val (n2, rng3) = rng2.nextInt val n2: Int = -1281479697 val rng3: RNG = SimpleRNG(197491923327988)
Follow the returned RNG rather than reusing the original one: each call yields a value and the precise state required for the next call. section 6.2
The pair is more than a workaround for random numbers. It separates computing a next state from communicating that state. This preserves referential transparency while keeping the state representation encapsulated: callers must handle the returned state, but need not know how that state is implemented. section 6.2 section 6.7
State actions compose because each action receives the state produced by the previous one:
- `unit(a)` returns a value without changing state. section 6.8
- `map` transforms an action’s result while preserving its state transition. section 6.5
- `flatMap` chooses a following action from the first result and runs it with the first action’s new state. section 6.8
- `map2`, `sequence`, and `traverse` combine independent descriptions into ordered stateful computations. section 6.8
The abstraction removes repeated tuple unpacking and repacking, not the state transition itself. `get` returns the current state as a value, `set` replaces it, and `modify` derives an update action from an S => S function. With these operations and composition, a program can describe a state machine using immutable states and explicit transitions. section 6.6 section 6.8
Candy dispenser simulation
Model a dispenser with locked status, remaining candies, and collected coins. Convert each Coin or Turn input into a State action that applies the transition rules, sequence or traverse those actions, then get the final Machine and return its coin and candy counts. Invalid inputs and empty dispensers leave the machine unchanged. section 6.6 section 6.8
State is a model of explicit state passing, not a claim that all implementation mutation is forbidden. Local mutation can remain unobservable behind a pure interface, while State is useful when the transition itself should be represented, composed, and controlled as a value. Scoped-mutation designs may reuse the same S => (A, S) shape for a different purpose: preventing mutable references from escaping. section 14.1 section 14.2.1






































