我对下一个方法有一个定义:
def add1(x: Int, y: Int) = x + y
def add2(x: Int)(y: Int) = x + y
Run Code Online (Sandbox Code Playgroud)
第二个是第一个的咖喱版。然后,如果要部分应用第二个功能,则必须编写val res2 = add2(2) _。一切顺利。接下来,我希望add1函数被处理。我写
val curriedAdd = (add1 _).curried
Run Code Online (Sandbox Code Playgroud)
我可以说curriedAdd类似add2吗?但是,当我尝试以curriedAdd这种方式部分申请时,val resCurried = curriedAdd(4) _出现编译错误。然后我将其修复为
val resCurried = curriedAdd(4)
Run Code Online (Sandbox Code Playgroud)
为什么a的结果Functions.curried与add function(from add2)的当前版本不同?
首先curriedAdd是相同add2 _和不同add2。add2 只是一个方法。
scala> curriedAdd\nres52: Int => (Int => Int) = <function1>\n\nscala> add2 _\nres53: Int => (Int => Int) = <function1>\nRun Code Online (Sandbox Code Playgroud)\n\n关于第二个问题。我认为原因如下。正在做
\n\nscala> val i = curriedAdd(23)\ni: Int => Int = <function1>\n\nscala> i _\nres54: () => Int => Int = <function0>\n\nscala> curriedAdd(23) _\n<console>:10: error: _ must follow method; cannot follow Int => Int\n curriedAdd(23) _\nRun Code Online (Sandbox Code Playgroud)\n\ncurriedAdd(23) _不起作用。让我们看一下 scala 手册 (\xc2\xa76.7)-
\n\n\n如果 e 是方法类型或者 e 是按名称调用参数,则表达式 e _ 格式良好。如果 e 是带参数的方法,则 e _\n 表示 e 通过 eta 扩展转换为函数类型 (\xc2\xa76.26.5)。\n 如果 e 是无参数方法或类型为 => 的按名称调用参数T ,\ne _ 表示 () => T 类型的函数,当将 e 应用于空参数列表 () 时,它会计算 e。
\n
请记住,它仅评估它是否是方法或按名称调用参数。在 中 curriedAdd(23) _,它不会评估 curriedAdd(23) 但检查它是否是方法或按名称调用。它不是方法,也不是名称调用参数。
它不是按名称,因为按名称是变量的属性。在上面,您在评估后得到一个按名称curriedAdd(23)参数,但curriedAdd(23)其本身并不是按名称变量。因此会出现错误(理想情况下编译器应该已经覆盖它)。请注意,以下内容有效:
scala> curriedAdd(23)\nres80: Int => Int = <function1>\n\nscala> res80 _\nres81: () => Int => Int = <function0>\nRun Code Online (Sandbox Code Playgroud)\n\n上面的方法之所以有效res80 _,是因为这里您正在申请_按名称调用,从而进行转换。