我对下一个方法有一个定义:

def add1(x: Int, y: Int) = x + y

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

第二个是第一个的 curry 版。然后,如果要部分应用第二个函数,则必须编写val res2 = add2(2) _。一切安好。接下来,我想add1函数被 curry 。我写
val curriedAdd = (add1 _).curried

我可以说curriedAdd与add2类似吗?
但是,当我尝试以curriedAdd这样的方式部分应用val resCurried = curriedAdd(4) _时,出现编译错误。然后我将其修复为
val resCurried = curriedAdd(4)

为什么Functions.curried的结果与add函数的 curry 版本(来自add2)不同?

最佳答案

首先,curriedAddadd2 _相同,而不是add2。 add2只是一种方法。

scala> curriedAdd
res52: Int => (Int => Int) = <function1>

scala> add2 _
res53: Int => (Int => Int) = <function1>

关于第二个问题。我认为以下是原因。正在做
scala> val i = curriedAdd(23)
i: Int => Int = <function1>

scala> i _
res54: () => Int => Int = <function0>

scala> curriedAdd(23) _
<console>:10: error: _ must follow method; cannot follow Int => Int
              curriedAdd(23) _
curriedAdd(23) _不起作用。让我们看一下scala手册(第6.7节)-



请记住,它仅评估它是方法还是按名称调用参数。在curriedAdd(23) _中,它不评估curriedAdd(23),而是检查它是否是方法或按名称调用。它既不是方法也不是“按名称调用”参数。

它不是按名称的,因为按名称是变量的属性。在上面的表达式中,在评估curriedAdd(23)之后会得到一个by-name参数,但是curriedAdd(23)本身不是一个by-name变量。因此,该错误(理想情况下,编译器应该已掩盖了该错误)。请注意以下工作:
scala> curriedAdd(23)
res80: Int => Int = <function1>

scala> res80 _
res81: () => Int => Int = <function0>

上面的方法是有效的,因为res80 _,在这里您将_应用于按名字调用参数,因此可以进行转换。

09-26 16:00