通过嵌套函数或多个参数列表进行 scala 柯里化 [英] scala currying by nested functions or by multiple parameter lists

查看:38
本文介绍了通过嵌套函数或多个参数列表进行 scala 柯里化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Scala 中,我可以定义一个带有两个参数列表的函数.

In Scala, I can define a function with two parameter lists.

def myAdd(x :Int)(y :Int) = x + y

这使得定义部分应用函数变得容易.

This makes it easy to define a partially applied function.

val plusFive = myAdd(5) _

但是,我可以通过定义和返回嵌套函数来完成类似的事情.

But, I can accomplish something similar by defining and returning a nested function.

  def myOtherAdd(x :Int) = {
    def f(y :Int) = x + y
    f _
  }

从表面上看,我已经移动了下划线,但这仍然感觉像柯里化.

Cosmetically, I've moved the underscore, but this still feels like currying.

val otherPlusFive = myOtherAdd(5)

我应该使用什么标准来选择一种方法而不是另一种方法?

What criteria should I use to prefer one approach over the other?

推荐答案

完成同一件事至少有四种方法:

There are at least four ways to accomplish the same thing:

def myAddA(x: Int, y: Int) = x + y
val plusFiveA: Int => Int = myAddA(5,_)

def myAddB(x: Int)(y : Int) = x + y
val plusFiveB = myAddB(5) _

def myAddC(x: Int) = (y: Int) => x + y
val plusFiveC = myAddC(5)

def myAddD(x: Int) = {
  def innerD(y: Int) = x + y
  innerD _
}
val plusFiveD = myAddD(5)

您可能想知道哪种最有效哪种风格最好(对于某些非基于性能的最佳衡量标准).

You might want to know which is most efficient or which is the best style (for some non-performance based measure of best).

就效率而言,事实证明这四种方法本质上是等效的.前两种情况实际上发出完全相同的字节码;JVM 对多个参数列表一无所知,因此一旦编译器弄清楚了(您需要在案例 A 上使用类型注释来帮助它),它在幕后都是一样的.第三种情况也非常接近,但由于它预先承诺返回一个函数并在现场指定它,因此可以避免一个内部字段.在完成的工作方面,第四种情况与前两种情况几乎相同;它只是在方法内部而不是外部转换为 Function1.

As far as efficiency goes, it turns out that all four are essentially equivalent. The first two cases actually emit exactly the same bytecode; the JVM doesn't know anything about multiple parameter lists, so once the compiler figures it out (you need to help it with a type annotation on the case A), it's all the same under the hood. The third case is also extremely close, but since it promises up front to return a function and specifies it on the spot, it can avoid one internal field. The fourth case is pretty much the same as the first two in terms of work done; it just does the conversion to Function1 inside the method instead of outside.

就风格而言,我建议 B 和 C 是最好的方法,具体取决于您在做什么.如果您的主要用例是创建一个函数,而不是使用两个参数列表就地调用,那么请使用 C,因为它会告诉您它将要做什么.(例如,这个版本对于来自 Haskell 的人来说也特别熟悉.)另一方面,如果您主要打算就地调用它但偶尔会使用咖喱,那么使用 B.同样,它更清楚地说明了什么预计会这样做.

In terms of style, I suggest that B and C are the best ways to go, depending on what you're doing. If your primary use case is to create a function, not to call in-place with both parameter lists, then use C, because it tells you what it's going to do. (This version is also particularly familiar to people coming from Haskell, for instance.) On the other hand, if you are mostly going to call it in place but will only occasionally curry it, then use B. Again, it says more clearly what it's expected to do.

这篇关于通过嵌套函数或多个参数列表进行 scala 柯里化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆