% Random number generation The source of this text is a [literate Haskell](http://www.haskell.org/haskellwiki/Literate_programming) file: [random.lhs](random.lhs) that you can download and load into GHC. We begin by importing the module [`System.Random`](http://hackage.haskell.org/package/random/docs/System-Random.html) for random number generation: \begin{code} import System.Random \end{code} Random numbers are generated by the function ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.haskell} randomR :: (Int,Int) -> StdGen -> (Int,StdGen) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (Here, the type is specialized for `Int`, but it also works for many other types.) The first argument is an (inclusive) interval which the result should lie within. The second argument `StdGen` is an abstract value used determine which random number to generate. The result is a random number and a new `StdGen` that can be used to generate new random numbers. To test `randomR` you first have to create an `StdGen`. Since `StdGen` is an abstract type, it can't be created directly, but only through a helper function, such as: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.haskell} mkStdGen :: Int -> StdGen ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Now the user can make up an integer and use that to generate random numbers; e.g: System.Random> fst (randomR (1,10) (mkStdGen 23456)) 8 System.Random> fst (randomR (1,10) (mkStdGen 98765)) 1 If you use the same interval and same `StdGen` many times, you will always get the same result: System.Random> fst (randomR (1,10) (mkStdGen 23456)) 8 System.Random> fst (randomR (1,10) (mkStdGen 23456)) 8 (After all, `randomR` is a pure function.) Now one might wonder what's the point of all of this. We're creating a random number from another random number that we had to make up ourselves. But it turns out that it is only for the first use of `randomR` that one has to create an `StdGen`. The result from `randomR` is a pair of a number and a new `StdGen`. By using the new `StdGen` to generate the next random number, it is possible to generate a sequence of independent random numbers. Here is one way to do that: \begin{code} fourRandomNums :: StdGen -> (Int,Int,Int,Int) fourRandomNums g0 = (a,b,c,d) where (a,g1) = randomR (1,10) g0 (b,g2) = randomR (1,10) g1 (c,g3) = randomR (1,10) g2 (d,g4) = randomR (1,10) g3 \end{code} Note how each `randomR` gets a differet `StdGen`. The above function generates four random numbers from a single `StdGen` (a "seed"): *Main> fourRandomNums (mkStdGen 234523) (4,6,10,1) But as before, we get the same result for the same `StdGen`: *Main> fourRandomNums (mkStdGen 234523) (4,6,10,1) If we want to avoid having to make up the seed ourselves, we can let the operating system do it for us, using `newStdGen`: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.haskell} newStdGen :: IO StdGen ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We can use `newStdGen` as follows: \begin{code} testFourRandomNums :: IO () testFourRandomNums = do g <- newStdGen print (fourRandomNums g) \end{code} Now we can finally generate independent random numbers without having to worry about seeds: *Main> testFourRandomNums (3,2,7,9) *Main> testFourRandomNums (7,6,9,9) *Main> testFourRandomNums (2,6,9,5)