我正在尝试在F#中开发一个随机数“生成器”。
我成功创建了以下功能:
let draw () =
let rand = new Random()
rand.Next(0,36)
这样可以正常工作,它会生成0到36之间的数字。
但是,我正在尝试创建一个多次运行此函数的函数。
我尝试了以下
let multipleDraws (n:int) =
[for i in 1..n -> draw()]
但是,我只得到一个结果,因为draw
在for comprehension中仅被评估一次。
如何强制多次执行draw
功能?
答案 0 :(得分:8)
问题在于随机类型。它使用计算机的时间生成种子,然后生成随机数。由于实际上调用的时间是相同的,因此生成相同的种子,因此也返回相同的数字。
这将解决您的问题:
let draw =
let rand = new Random()
fun () ->
rand.Next(0,36)
然后:
let multipleDraws (n:int) =
[for i in 1..n -> draw()]
答案 1 :(得分:6)
添加此内容以帮助解释Ramon的答案。
此代码使用lambda函数。
let draw =
let rand = new Random()
fun () ->
rand.Next(0,36)
如果给lambda函数命名,可能更容易理解发生了什么。
let draw =
let rand = new Random()
let next() =
rand.Next(0,36)
next
接下来为变量draw赋值。您可以将rand和next移出绘图范围以直接查看赋值。
let rand = new Random()
let next() =
rand.Next(0,36)
let draw = next
从上面的代码可以看出,在Ramon的回答中,新的Random只被调用一次,而在SRKX的例子中被多次调用。
如Ramon Random所述,基于随机种子生成一系列数字。如果使用相同的种子,它将始终生成相同的数字序列。您可以随机传递种子new Random(2)
。如果您没有传递值,则使用当前时间。因此,如果你连续多次调用新的Random而没有种子,它很可能会有相同的种子(因为时间没有改变)。如果种子没有改变,那么序列的第一个随机数将始终相同。如果您尝试使用SRKX的原始代码并使用足够大的数字调用multipleDraws,那么时间将在循环期间发生变化,您将获得一系列经常更改的数字。