我对下一个方法有一个定义:
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
)不同? 最佳答案
首先,curriedAdd
与add2 _
相同,而不是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 _
,在这里您将_
应用于按名字调用参数,因此可以进行转换。