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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With