最近,我遇到了有趣但烦人的F Sharp行为。根据[1],“F#自动缓存任何不带参数的函数的值。”这似乎是一个好主意,但是当我尝试提供一个包装函数来生成随机数时,这给我带来了麻烦。
举个例子,在这个问题的结尾,我在代码中有两个不同的功能。第一个函数“getRand”不带任何参数,但不幸的是,它始终返回相同的数字。第二个函数“getRand2”的工作原理与我期望的一样,每次调用时都会生成一个新的随机数,但它烦人地使用了无用且被忽略的额外参数。
如果可能的话,我希望拥有getRand2的功能,但又希望拥有getRand的便利。是否有我可以应用于getRand的编译器指令或特殊关键字,它们将关闭其功能缓存功能,并因此使其行为类似于getRand2?
谢谢
肖恩
注意:如果答案已经出现在[1]中,请原谅我,但我现在还没有看到。
[1]-http://en.wikibooks.org/wiki/F_Sharp_Programming/Caching
(* Always returns the same number *)
let getRand =
let seed = int32(System.DateTime.Now.Ticks)
let randGen = new System.Random(seed)
randGen.Next()
(* Works as expected except I need an annoying extra parameter *)
let getRand2 dummyParam =
let seed = int32(System.DateTime.Now.Ticks)
let randGen = new System.Random(seed)
randGen.Next()
(* Outputs three "identical" numbers to console *)
System.Console.WriteLine(
"Parameterless getRand always outputs same number.")
System.Console.WriteLine(getRand)
System.Threading.Thread.Sleep(100)
System.Console.WriteLine(getRand)
System.Threading.Thread.Sleep(100)
System.Console.WriteLine(getRand)
System.Console.WriteLine()
(* Outputs three "different" numbers to console *)
System.Console.WriteLine(
"GetRand2 works as expected even though second dummy param is always the same.")
System.Console.WriteLine(getRand2 0)
System.Threading.Thread.Sleep(100)
System.Console.WriteLine(getRand2 0)
System.Threading.Thread.Sleep(100)
System.Console.WriteLine(getRand2 0)
System.Console.WriteLine()
最佳答案
只是为了澄清一下,我认为“不带参数的函数”这一短语具有误导性。根据定义,函数会将值从函数的域映射到函数范围内的值,因此所有函数都带有参数。在您的情况下,getRand
没有绑定(bind)到函数,它只是int
类型的值。
如果我正确理解了您的问题,我认为您想做
let getRand =
let seed = int System.DateTime.Now.Ticks
let randGen = new System.Random(seed)
fun () -> randGen.Next()
您仍然需要调用
getRand
作为一个函数(getRand()
,而不仅仅是getRand
),但是无法解决此问题-int
值始终保持不变是推理程序的关键特性。您可以使用与我的
getRand2
版本几乎相同的方式来使用getRand
函数:由于您不在体内使用dummyParam
,因此F#使该函数具有通用性,这意味着您可以根据需要将单位值()
作为参数传递。 但是,您的getRand2
函数已损坏,因为它在每次调用时都会创建一个新的随机数生成器。这意味着,如果在一个刻度内两次调用它,您将得到相同的答案:let x,y = (getRand2(), getRand2())
这就是为什么在匿名函数范围之外定义
seed
和randGen
如此重要的原因。关于f# - 是否为特定功能关闭FSharp功能缓存?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6554933/