A pseudo-random number generator deterministically produces values that approximate randomness from an initial seed. The central design tension is whether generation mutates hidden state or returns the next state explicitly. section 6.0 section 6.8
Two interfaces expose the difference between effectful and purely functional generation:
- scala.util.Random stores and updates internal state; repeated calls consume that state, making failures difficult to reproduce unless both the seed and call history match. section 6.1
- A functional RNG returns both the generated value and a new RNG, leaving the previous state unchanged and giving the caller control over state progression. section 6.2
- The pattern generalizes as Rand[A], a function from Rng to a value and updated Rng, with combinators such as unit, map, map2, flatMap, and sequence. section 6.8
A deterministic functional sequence
Starting with SimpleRNG(42), the first call returns 16159453 and a new RNG; calling that returned RNG produces -1281479697 and another new RNG. Repeating the same sequence reproduces the same values. section 6.2
Listing 6.1 Using scala.util.Random to generate random numbers
scala> val rng = new scala.util.Random #1 scala> rng.nextDouble val res1: Double = 0.9867076608154569 scala> rng.nextDouble val res2: Double = 0.8455696498024141 scala> rng.nextInt val res3: Int = -623297295 scala> rng.nextInt(10) #2 val res4: Int = 4
Compare successive calls to scala.util.Random, including bounded integer generation, before replacing hidden mutation with explicit state. section 6.1









