% 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 [declaring a module name](http://learnyouahaskell.com/modules#making-our-own-modules) and importing the module [`System.Random`](http://hackage.haskell.org/package/random/docs/System-Random.html) for random number generation:

\begin{code}
module RandomNumbers where

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 as to initialize the random number generation. 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 actually 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)