在Haskell中通过getStdGen使用全局随机生成器

the*_*ppo 4 haskell functional-programming

我刚刚开始学习Haskell阅读"让你学习哈斯克尔非常棒!" 书中有一个例子对我没有意义.它说以下代码会输出两次相同的随机字符串:

main = do
    gen <- getStdGen
    putStrLn $ take 20 (randomRs ('a','z') gen)
    gen2 <- getStdGen
    putStrLn $ take 20 (randomRs ('a','z') gen2)
Run Code Online (Sandbox Code Playgroud)

另一方面,如果同一个程序被调用两次,那么毫无疑问会产生不同的输出.此外,如果我将它与下面的代码进行比较,这会产生不同的值s1s2:

main = do
    s1 <- getLine
    s2 <- getLine
    putStrLn s1
    putStrLn s2
Run Code Online (Sandbox Code Playgroud)

我想知道上面两个例子是如何不同的.

lef*_*out 6

这只是一个特定的属性getStdGen:不像getLine,它不是一个"有效的"IO动作,而是每次评估它时只访问相同的默认随机生成器状态.因此它几乎是一个纯粹的函数,但由于它在不同的程序运行之间会有所不同(实际上在同一个运行中,如果你明确地修改setStdGen),它们仍然把它放在IOmonad中.

也许这是一个很好的类比:

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)
Run Code Online (Sandbox Code Playgroud)