我如何在函数中使用getStdGen

Gwe*_*ong 5 random haskell

我是haskell的新手,特别是Random类型,当我遇到这个时,我正在查看learnyouahaskell教程

import System.Random  

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

但是,当我尝试在函数中使用它时,这会失败(即)

genrandTF:: Int -> StdGen -> [Bool]
genrandTF number gen =  take number (randomRs (True, False) gen)
Run Code Online (Sandbox Code Playgroud)

并通过它来调用它

genrandTF 20 getStdGen
Run Code Online (Sandbox Code Playgroud)

这是为什么?

-update-

我得到的错误是

<interactive>:116:15:
    Couldn't match expected type `StdGen' with actual type `IO StdGen'
    In the second argument of `genrandTF', namely `(getStdGen)'
    In the expression: genrandTF 20 (getStdGen)
Run Code Online (Sandbox Code Playgroud)

当我将其更改为输入IO StdGen时,我无法编译,因为我收到此消息:

No instance for (RandomGen (IO StdGen))
  arising from a use of `randomRs'
In the second argument of `take', namely
  `(randomRs (True, False) gen)'
In the expression: take number (randomRs (True, False) gen)
In an equation for `genrandTF':
    genrandTF number gen = take number (randomRs (True, False) gen)
Run Code Online (Sandbox Code Playgroud)

CR *_*ost 5

这是初学者常犯的错误。getStdGen是一个具有类型的值IO StdGen;换句话说,它不是一个StdGen计算机程序,而是一个计算机程序,当它完成时,将包含 Haskell 可以用作StdGen.

您需要运行该程序来获取StdGen(通过unsafePerformIO——顾名思义,这破坏了 Haskell 中的几个安全保证),或者您需要将该函数与该程序结合起来以创建一个新程序。(习惯上,Haskell I/O 是一堆与 I/O 操作交错的 Haskell 操作。)

做你想做的事情的最简单的方法是:

fmap (genrandTF 20) getStdGen
Run Code Online (Sandbox Code Playgroud)

它使用 的Functor实例IO