Randomness Setup
Note
These functions requireimport System.Random
.
Source: LYaH, Input and Output.
Haskell functions are pure, which means the same input must give the same output. A “random number generator” that just puts out different numbers each time you call it is not pure. Instead, in Haskell, the randomization functions output a random value and a new random number generator that will give different results.
Making a StdGen
The best default choice is to use a newStdGen
. You could also use
mkStdGen
if you want to specify the initial “seed” (so the random
numbers will all follow the same pattern every time you run the program).
Notice the use of let
and <-
in the examples.
-
newStdGen
: An IO function that uses the system’s random number state to create a random number generator that gives different results every time you run it. -
mkStdGen
: Provide a seed number, like 109211, and get a random number generator that will produce the same results on every run. Good for debugging.
The code below creates two standard generators. This is just an example. Normally you would only use one.
main = do rng1 <- mkStdGen 109211
rng2 <- newStdGen
putStrLn "OK"
Getting Random Numbers
-
In your
main
method, you can get a random number by callingrandomIO
. This method avoids using a standard generator, but it only works inmain
. Note the use of<-
.main = do n <- randomIO :: IO Int let m = n `mod` 20 -- 0<=m<20 print m
-
In another function, use
random
. Make sure you have a type sigature so Haskell knows what to output.rand20 :: StdGen -> (Int, StdGen) rand20 gen = (n `mod` 20, gen') where (n, gen') = random gen main = do g <- newStdGen let (n,g2) = rand20 g print n
-
(
randomR
) TherandomR
function gives a random numberr
in a rangelow <= r <= high
. Notice that both ends of the range are included.main = do gen <- newStdGen let (n, gen') = randomR (1,6) gen :: (Int, StdGen) print n
Common Problems
- Copy and pasting examples can mess up indentation. All of the items
in a
do
-block need to line up vertically - Variables: regular variables like
let x = 5
use a different syntax from “IO variables” likey <- newStdGen
.
Notes
- Avoid
getStdGen
. CallinggetStdGen
repeatedly will give the exact same random number generator each time. (It does not “advance the state”.) If you ever have more than one standard generator at a time, this will not be what you want.