liveBook · Manning

Rand

As explained in Functional Programming in Scala, Second Edition

Rand is a type alias for a state-transition function that accepts an RNG and returns a value together with a new RNG.

Rand[A] is a type alias for RNG => (A, RNG). It represents a state action: a program that consumes an RNG, produces an A, and returns the next RNG without mutating state. section 6.4 section 6.8

type Rand[+A] = RNG => (A, RNG)

The alias makes state actions easier to name while preserving their underlying function representation. section 6.4

A direct implementation must repeatedly unpack a value and manually pass the returned RNG into the next computation. Rand separates that bookkeeping from the calculation being expressed. section 6.8

Rand actions can be composed through a small set of combinators:

  • unit creates an action that returns a constant and leaves the RNG unchanged. section 6.4
  • map transforms an action’s result without changing how the resulting RNG is threaded. section 6.4
  • map2 combines two actions, passing the RNG returned by the first into the second. section 6.8
  • flatMap uses a generated value to choose the next Rand action, enabling retries and value-dependent computation. section 6.4.2
  • sequence turns a list of Rand actions into one action producing a list of results. section 6.8

A testable die roll

A die roll can be built from a bounded random action: `def rollDie: Rand[Int] = map(nonNegativeLessThan(6))(_ + 1)`. The bounded generator uses flatMap to retry values that would make modulo-based selection skewed. Supplying the same RNG state reproduces the same result, making the off-by-one error observable and testable. section 6.4.2 section 6.4.2

The pattern generalizes beyond randomness. State[S, A] uses the same function shape, S => (A, S), and the same combinators to remove manual state threading from other stateful computations. section 6.8

How Functional Programming in Scala, Second Edition covers it

How deep it goes
Defines the function representation and develops unit, map, map2, flatMap, and sequence, including rejection-based retry.
Examples
Uses integer and double generators, nonNegativeEven, nonNegativeLessThan, rollDie, and lists of generated values.
What it assumes
Assumes an RNG and basic function types while making explicit state threading and purity central to the design.
What you can do after
Build it from scratch as pure, reproducible random computations composed with standard state-action combinators.
How it connects
Connects RNG, state actions, pure functions, map, flatMap, sequence, and the generalized State data type.

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.