我是haskell的新手,特别是Random类型,当我遇到这个时,我正在查看learnyouahaskell教程
import System.Random
main = do
gen <- getStdGen
putStr $ take 20 (randomRs ('a','z') gen)
但是,当我尝试在函数中使用它时,这会失败(即)
genrandTF:: Int -> StdGen -> [Bool]
genrandTF number gen = take number (randomRs (True, False) gen)
并通过
调用它genrandTF 20 getStdGen
为什么会这样?
-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)
当我将其更改为输入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)
答案 0 :(得分:4)
这是初学者的常见错误。 getStdGen
是一个类型为IO StdGen
的值;换句话说,它不是StdGen
,而是一个计算机程序,当它完成时,它将包含Haskell可以用作StdGen
的东西。
你需要运行程序来获取StdGen
(通过unsafePerformIO
- 顾名思义这会破坏Haskell中的几个安全保证),或者你需要结合使用与程序一起制作新程序。 (惯用法,Haskell I / O是一堆与I / O操作交织的Haskell操作。)
做你想做的最简单的方法是:
fmap (genrandTF 20) getStdGen
使用Functor
的{{1}}实例。
答案 1 :(得分:-2)
来自randomR
的{{1}}(randomRs
内部使用):
未指定如果lo> hi
会发生什么
(在randomR (lo,hi)
中调用时。
现在True > False
,所以你在这里遇到了未指明的行为。尝试使用(False,True)
(除了修复与IO
相关的错误)。