2017-08-25 241 views
0

我之前创建了此函数来生成整数范围为(m,n)的随机数。在Haskell中运行多个函数

giveRand :: Random c => c -> c -> c 
giveRand m n = unsafePerformIO . getStdRandom $ randomR (m,n) 

从这种情况下,我想多次使用相同的参数运行它,这样它会返回我随机生成值的列表中给定的范围内。我尝试了复制功能,但它只复制了giveRand的结果。它没有创建函数的多个副本并重新评估它。

从这个问题我想知道是否有一个函数,允许我用相同的参数多次运行任何函数。我会问这个例子,即使输入范围相同,也可能出现不同的值。

那么,Haskell中是否有任何函数使我能够使用相同的参数多次运行函数?

+2

你是不可能找到任何标准组合子要做到这一点,因为所有通用代码将被编写为标准假设,即Haskell函数为相同的参数返回相同的结果。您使用'unsafePerformIO'扔掉的设施是您可以找到允许您将“生成随机数”转换为“生成随机数列表”的代码的地方。 – Ben

+6

我第二@本的观点。 (我们Bens必须坚持在一起。)'unsafePerformIO'是你混乱的根源。我强烈建议忘记存在'unsafePerformIO'。这意味着专家用户 - 这个名字是为了吓跑你!你需要的情况确实非常罕见,这不是其中之一。花费你的努力学习如何使用'IO'类型来代替。这很值得! –

回答

8

忘记unsafePerformIO;承认你正在做一些有状态的事情。具体方法如下:

Control.Monad System.Random> replicateM 3 (randomRIO (5,7)) 
[6,7,5] 

如果你不能这样做IO,你也可以让有状态的明确与State单子:

Control.Monad.State System.Random> runState (replicateM 3 (state (randomR (5,7)))) (mkStdGen 0) 
([7,7,5],1346387765 2103410263) 
+1

或者,如果您不关心最终生成器状态,则可以干净地使用'evalState' - 这非常类似于由'runState'组成的'fst'。例如:'evalState(replicateM 3(state(randomR(5,7))))(mkStdGen 0) [7,7,5]' –