2015-03-31 22 views
1

我在看FoldLeft和FoldRight方法,并且该方法的操作符版本非常奇特,就像这样(0 /:List.range(1,10))(+)。 对于具有两个参数列表的右联合函数,人们可能会认为语法是这样的(HostClass((param1)(param2))。 但在这种情况下,它是语法(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)?

是否有一种解决方法来调用重载测试:函数中没有任何歧义。

+0

试''DEF测试:'(X:字符串,Y:字符串)= {X +”“+ Y}' – 2015-03-31 08:16:06

回答

1

斯卡拉的类型系统只考虑函数的第一个参数列表进行类型推断。因此,为了唯一标识一个类或对象中的一个重载方法,该方法的第一个参数列表对于每个重载定义都必须是不同的。这可以通过以下示例来演示。

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) 
0

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

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

你会得到同样的错误与点符号:

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

如果重命名一个PARAM列表功能,模糊性将消失,

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

将编译。