liveBook · Manning

State

As explained in Functional Programming in Scala, Second Edition

State is a parameterized state-transition abstraction that represents computations producing a value while transforming an underlying state.

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

How Functional Programming in Scala, Second Edition covers it

How deep it goes
Defines State as S => (A, S) and develops composition, get/set/modify, and state-machine simulation.
Examples
Uses a functional RNG and a coin-operated candy dispenser driven by Coin and Turn inputs.
What it assumes
Assumes basic Scala functions and pairs while introducing State from concrete random-number generation.
What you can do after
Build it from scratch as a generic State type and compose state-machine transitions with standard combinators.
How it connects
Connects State to referential transparency, random number generation, map, flatMap, sequence, traverse, and finite state automata.

Also explained in

Compare how 39 books explain state →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Functional Programming in Scala, Second Edition. The section links point to the parts of the book it draws on.