liveBook · Manning

System.Random

As explained in Learn Haskell by Example

System.Random is a Haskell library module providing functions, types, and type classes for generating random values.

System.Random provides functions, types, and type classes for generating pseudo-random values of different types. Add the random package to package.yaml, for example with random >= 1.2.1.1. The module includes older deprecated interfaces; current code should prefer System.Random.Stateful, while StdGen remains a typical pseudo-random generator. section 9.1.2

Random generation is state-passing: a generator produces a value and a new generator state, and repeatedly feeding that state forward creates a sequence. StdGen supports this explicit style without requiring a hand-written linear congruential generator. section 9.1.2

Generate values through the global generator

The older getStdGen and setStdGen actions retrieve and replace copies of a global StdGen, so callers must write the updated generator back. This approach is not safe for concurrent usage. The safer Stateful interface applies a generation function atomically: applyAtomicGen random globalStdGen :: IO Int, or applyAtomicGen (uniformR (0, 100)) globalStdGen :: IO Float. A reusable wrapper can expose the same pattern as applyGlobalStdGen. section 9.1.4

Listing 9.2 Functions to explicitly work with random state
newtype RandomState = RandomState Int
 deriving (Eq, Show)  #1

randomInt :: RandomState -> (Int, RandomState)
randomInt (RandomState rs) = (newRs, RandomState newRs)  #2
  where
    newRs = (1103515245 * rs + 12345) `mod` (2 ^ 31)  #3

randomIntList :: RandomState -> Int -> [Int]
randomIntList rs n
  | n <= 0 = []                        #4
  | otherwise =
    let (v, rs') = randomInt rs        #4
     in v : randomIntList rs' (n - 1)  #4

Inspect the explicit RandomState example to see how each generated integer returns a replacement state and how recursion builds a list. section 9.1.2

ghci> applyAtomicGen random globalStdGen :: IO Int
-8749052575918541620
ghci> applyAtomicGen (uniformR (0, 100)) globalStdGen :: IO Float
60.164364
ghci> applyAtomicGen randomList' globalStdGen :: IO [Bool]
[True,False,False,True,True,False,False,False,True,True,True,True,True,
 False,True,False,False,False,False,True,True,True,False,True,True,
 False,False,False,True,False,False,True,False,True,True,False,True,
 True,True,False,False,False,False,True,True,True,False,False,False,
 True,False,False,False,True,False,False,True,True,True]

Compare atomic global generation for integers, bounded floating-point values, and lists of booleans. section 9.1.4

How Learn Haskell by Example covers it

How deep it goes
Explains explicit state threading and global access, but defers the broader Stateful generator interface beyond StdGen.
Examples
Uses randomIntList, randomListIO, random, uniformR, applyAtomicGen, and generated integers, floats, booleans, and lists.
What it assumes
Assumes basic Haskell functions and IO, while teaching generator state passing and global-state pitfalls through code.
What you can do after
Apply it via System.Random.Stateful to generate typed or bounded values while updating an explicit or atomic global generator.
How it connects
Connects pseudo-random generators with IO actions, StdGen, System.Random.Stateful, AtomicGenM, and concurrency safety.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Haskell by Example. The section links point to the parts of the book it draws on.