Using global random generator via getStdGen in Haskell

functional-programming, haskell

Solution

This is just a specific property of `getStdGen`: unlike `getLine`, it is not an "effectful" IO action, but just accesses the same default random-generator state each time you evaluate it. It is thus almost a pure function, but since it'll be different between different program runs (and indeed within the same run, if you explicitly modify with `setStdGen`), they've nevertheless put it in the `IO` monad.

Perhaps a good analogy is this:

main = do
    file <- readFile "/etc/bash.bashrc"  -- or any other persistent system file
    putStrLn $ head (lines file)
    file2 <- readFile "/etc/bash.bashrc"
    putStrLn $ head (lines file2)

Problem

I've just started learning `Haskell` with the enjoyable reading of "Learn you a Haskell for great Good!" and there is an example in the book which doesn't make sense to me. It says that the following code would output the same random string twice: ``` main = do gen <- getStdGen putStrLn $ take 20 (randomRs ('a','z') gen) gen2 <- getStdGen putStrLn $ take 20 (randomRs ('a','z') gen2) ``` On the other hand, if the very same program is called twice it would undoubtedly yield different outputs. Moreover, that doesn't seem consistent if I compare it to the code below which yields different values of `s1` and `s2`: ``` main = do s1 <- getLine s2 <- getLine putStrLn s1 putStrLn s2 ``` I'm wondering how the above two examples are different.

Original source