f# - 是否可以在 F# 中使用正常顺序评估

标签 f# operator-precedence

在 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/

相关文章:

Fortran 指数运算顺序

javascript - 为什么 Javascript 中的变量赋值运算符优先级会以其他方式工作

arrays - F# - 什么是数组<'T>?

f# - 为什么 Seq 在迭代大型 csv 文件时会出现堆栈溢出

C++ 后缀表达式未定义与未指定行为

c++ - 运算符重载优先级

c - 为什么这些构造使用增量前和增量后未定义的行为?

F# 递归类型到 SQL 表

f# - 结合类型测试和文字的模式

string - 在 F# 中将 seq<string> 转换为 string[]