【问题标题】:Higher Order Function w/ Call By-Name?具有按名称调用的高阶函数?
【发布时间】:2016-07-07 02:46:13
【问题描述】:

给定:

def higherOrderCallByName(f: => Int => Int, x: Int): Int = f(x)
def higherOrderCallByValue(f: Int => Int, x: Int): Int = f(x)

在什么情况下对函数参数使用按名称调用是惯用/正确的,即higherOrderCallByName中的f

【问题讨论】:

  • 如果由于某种原因生成函数是一个昂贵的调用?
  • 我不认为这有什么区别,因为 scala 函数默认是按名称调用的。将函数作为参数传递并使其按值调用没有任何区别。我已经用一个小演示功能对此进行了测试。如果我错了,请纠正我。
  • @ManjeetKumar scala 函数默认是按名称调用的 你能用一个例子来支持吗?我认为通常它是按价值计算的。请参阅下面的示例。
  • @SudhirSingh :scala 函数默认是按值调用的。这是我的错误,我已经互换了术语。

标签: scala


【解决方案1】:

澄清一下,在call-by-value中,参数的值是在传递给函数之前确定的,而在call-by-name中参数的评估被推迟到函数内部使用。

我同意 m-z,higherOrderCallByName 在传递的函数可能是昂贵的调用时完全有效。

我能想到的另一种情况是,如果传递的函数有一些副作用,那么按名称参数的行为将不同于按值参数。我已经修改了你的例子来证明这一点:

def higherOrderCallByName(f: => Int => Int, x: Int): Int = {
  println("Inside by-name function.")
  f(x)
}

def higherOrderCallByValue(f: Int => Int, x: Int): Int = {
  println("Inside by-value function.")
  f(x)
}

def funWithSideEffect() : (Int) => Int = {
  println("Some side effect.") // some side-effect or some expensive call
  x => x + 1    // returns function which increments param
}

现在如果你调用higherOrderCallByValue(funWithSideEffect(), 2),输出将是:

Some side effect.
Inside by-value function.

正如输出所示,副作用发生在higherOrderCallByValue 的主体执行之前。

higherOrderCallByName(funWithSideEffect(), 2) 的输出将类似于:

Inside by-name function.
Some side effect.

当遇到f(x) 时,内部 higherOrderCallByName 出现副作用的地方。现在想象一下f(x)higherOrderCallByName 内多次执行的场景。显然它会对您的应用程序产生很大影响。

【讨论】:

  • 那么,除了副作用的情况,还有什么原因会导致函数“昂贵”?
  • 如前所述,funWithSideEffect 还可以进行一些昂贵的处理。基于此,您还想决定是否可以将计算推迟一段时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-11
  • 1970-01-01
  • 2018-07-27
  • 2019-06-15
  • 1970-01-01
  • 1970-01-01
  • 2020-04-04
相关资源
最近更新 更多