在 Scala 中,您可以在应用或正常顺序评估之间进行选择,请参阅“Scala call-by-name (=>) vs call-by-type ”为例。
def byName(a: => Unit) = {
for (i <- 0 until 10) {println(a)}
}
def byValue(a: Unit) = {
for (i <- 0 until 10) {println(a)}
}
var i = 1;
byValue(i = i + 1)
println(i); // 2
byName(i = i + 1)
println(i) // 12
在 F# 中也有可能吗?
最佳答案
正如 Lee 指出的那样,F# 不允许您指定函数参数的计算策略。这当然是一个有用的功能,但我认为它有时可能会令人困惑-例如,如果您有像 int -> int
这样的一流功能,那么类型不会告诉您要使用什么评估策略,因此您必须使类型更复杂或将其限制为命名函数。
除了显式使用 lambda 函数外,F# 还使用 lazy
提供对惰性求值(即,延迟求值,但缓存结果)的支持。关键字和 Lazy<'T>
类型:
let foo (a:Lazy<int>) (b:Lazy<int>) =
if a.Value = 0 then 0
else b.Value
仅当第一个参数不为零时,此函数才会评估第二个参数:
foo (lazy (printfn "a"; 0)) (lazy (printfn "b"; 10)) // Prints just 'a'
foo (lazy (printfn "a"; 10)) (lazy (printfn "b"; 10)) // Prints both 'a' and 'b'
这在语法上比使用函数更轻量级,但它仍然需要在调用站点上进行显式规范,而不仅仅是在声明站点上。
关于f# - 是否可以在 F# 中使用正常顺序评估,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15681865/