具有两个参数列表的右关联函数

时间:2015-03-31 05:09:53

标签: scala

我正在查看FoldLeft和FoldRight方法,该方法的运算符版本非常奇特,就像这样(0 /:List.range(1,10))( + ) 。 对于具有两个参数列表的右关联函数,可以预期语法是这样的((param1)(param2)op HostClass)。 但在这种情况下它是语法(param1 op HostClass)(param2)。这导致了另一种情况的歧义,其中右关联函数返回另一个采用单个参数的函数。 由于这种歧义,类编译但是在进行函数调用时失败,如下所示。

class Test() {
val func1:(String => String) = { (in) => in * 2 }    
def `test:`(x:String) = { println(x); func1 }
def `test:`(x:String)(y:String) = { x+" "+y }
}

val test = new Test

(("Foo") `test:` test)("hello")
<console>:10: error: ambiguous reference to overloaded definition,
both method test: in class Test of type (x: String)(y: String)String
and  method test: in class Test of type (x: String)String => String
match argument types (String)
              (("Foo") `test:` test)("hello")

所以我的问题是

这是预期的行为还是错误?

为什么两个参数列表右关联函数调用已经按照它的方式设计,而不是我认为更直观的语法((param1)(param2)op HostClass)?

是否有一种解决方法可以调用任何重载的test:function而不会产生歧义。

2 个答案:

答案 0 :(得分:1)

Scala的类型系统仅考虑类型推断函数的第一个参数列表。因此,为了唯一地标识类或对象中的重载方法之一,方法的第一参数列表必须对于每个重载定义是不同的。这可以通过以下示例来说明。

object Test {
 def test(x:String)(y:Int) = { x+" "+y.toString() }
 def test(x:String)(y:String) = { x+" "+y }
}

Test.test("Hello")(1)
<console>:9: error: ambiguous reference to overloaded definition,
both method test in object Test of type (x: String)(y: String)String
and  method test in object Test of type (x: String)(y: Int)String
match argument types (String)
              Test.test("Hello")(1)

答案 1 :(得分:0)

它在运行时真的失败了吗?当我测试它时,类会编译,但方法test:的调用不会。

我认为问题不在于操作符语法,而在于您有两个重载函数,一个只有一个,另一个有两个参数列表。

点符号会出现同样的错误:

test.`test:`("Foo")("hello")

如果重命名one-param list函数,则歧义将消失

(("Foo") `test:` test)("hello")

将编译。