Scala语法部分

时间:2016-07-19 02:24:12

标签: scala

当我创建部分功能时,为什么我不能立即调用它?

res6和res8都是相同的类型(function1)所以我不确定res7是如何工作的(立即调用它)以及res9将失败的原因

scala> ((x: Int) => x + 1)
res6: Int => Int = <function1>

scala> ((x: Int) => x + 1)(1)
res7: Int = 2

scala> def adder(a: Int, b: Int) = a + b
adder: (a: Int, b: Int)Int

scala> adder(1, _: Int)
res8: Int => Int = <function1>

scala> adder(1, _: Int)(1)
<console>:12: error: Int does not take parameters
       adder(1, _: Int)(1)
                       ^

scala> (adder(1, _: Int))(1)
res10: Int = 2

2 个答案:

答案 0 :(得分:1)

我认为你刚刚找到了一个小的Scala编译器怪癖。

我不知道这个案例是如何在解析器中完全实现的,但从它的外观来看,Scala认为你正在调用一个带有多个参数列表的函数(格式为f(...)(...))。因此,您需要在此处使用括号显式包围部分应用的函数,以便编译器可以消除f()()f(_)()形式之间的歧义。在res8中,您在函数后面没有任何参数,因此没有歧义。否则,如果您省略参数列表,Scala会要求您使用下划线跟随该函数:f _f() _

您仍然可以立即应用res10中显示的功能。

答案 1 :(得分:1)

adder(1, _: Int)

这是由scala编译器将其扩展为:

引起的
((x: Int) => adder(1, x)(1)) 

这是因为编译器无法推断出通配符的上下文,例如:

_ + _
scala> _ + _
<console>:17: error: missing parameter type for expanded function ((x$1, x$2) => x$1.$plus(x$2))
 _ + _
   ^
<console>:17: error: missing parameter type for expanded function ((x$1: <error>, x$2) => x$1.$plus(x$2))
   _ + _

所以你可以按照你的方式使用上下文界限:

(adder(1, _: Int))(1)

它将被扩展为:

((x: Int) => adder(1, x))(1)