`random` generates a value and the next random generator in one step. Its type is `random :: (Random a, RandomGen g) => g -> (a, g)`: the requested result type selects a `Random` instance, while the generator is returned so later calls can continue the sequence. section 9.1.3 section 9.1.6
ghci> import System.Random
ghci> import System.Random.Stateful
ghci> g = mkStdGen 100
ghci> g
StdGen {unStdGen = SMGen 16626775891238333538 2532601429470541125}
ghci> random g :: (Int, StdGen)
(9216477508314497915,StdGen {unStdGen = SMGen 712633246999323047
2532601429470541125})
A seeded `StdGen` passed to `random` produces an `Int` together with a changed `StdGen`; use the returned generator for the next value. section 9.1.3
Use `random` differently depending on how randomness is managed:
- In pure code, pass a generator in and thread the returned generator through every call that needs another value. section 9.1.3 section 9.6
- Choose the result type at the call site, such as `Int`, `Bool`, or `Double`, when a matching `Random` instance exists. section 9.1.6
- Use `randomR` for a range; use `uniform` or `uniformR` when uniform distribution is required for a supported type. section 9.1.3
- Wrap global-generator access in `IO` when explicit generator passing is too cumbersome, then compose higher-level generators around that action. section 9.1.3 section 9.1.6
Building a random list
A recursive list generator calls `random gen` to obtain `v` and `gen'`, then calls itself with `gen'`. Its base case returns the unchanged generator. A companion function can use `uniformR (0, maxVal)` to choose a manageable list length before generating the elements. section 9.1.3
`RandomIO a` packages an `IO a` action for generated values. Its `one` constructor uses `random`, while `some` chooses a length and repeats generation. Filters such as `suchThat` can restrict outputs, enabling generators for nonnegative numbers, ASCII characters, letters, and strings used by property tests. section 9.1.6 section 9.6
