System.Random.Stateful provides a modern interface for generating random values of many types. The examples focus on StdGen, a typical pseudo-random generator, and contrast its safer interface with deprecated random-generation functions. section 9.1.2 section 9.1.4
The main practical pieces are:
- Add random, for example random >= 1.2.1.1, to package.yaml dependencies. section 9.1.2
- Use StdGen explicitly when a function receives and returns generator state alongside its random result. section 9.1.2
- Use globalStdGen with applyAtomicGen to update the global generator atomically inside IO actions. section 9.1.4
- Use random for general random values or uniformR for bounded values such as a range from 0 to 100. section 9.1.4
Generating a random value in IO
applyGlobalStdGen :: (StdGen -> (a, StdGen)) -> IO a applyGlobalStdGen f = applyAtomicGen f globalStdGen This convenience function lets an IO action generate values without receiving or initializing a StdGen. For example, applyAtomicGen random globalStdGen :: IO Int produces an Int, while applyAtomicGen (uniformR (0, 100)) globalStdGen :: IO Float produces a bounded Float. The atomic update makes this global-generator pattern safe for concurrent use. section 9.1.4
Listing 9.5 An IO action that applies a function to the global pseudo-random generator
applyGlobalStdGen :: (StdGen -> (a, StdGen)) -> IO a applyGlobalStdGen f = applyAtomicGen f globalStdGen #1
Inspect the compact wrapper that applies a StdGen transformation to the atomic global generator. section 9.1.4
