换句话说,为什么这不应该编译?
def f(xs: List[Int]) = xs.foldLeft(0) _ // OK
def f(xs: List[Int]) = (xs :\ 0) _ // OK
def f(xs: List[Int]) = (0 /: xs) _
<console>:15: error: missing arguments for method /: in trait TraversableOnce;
follow this method with `_' if you want to treat it as a partially applied function
以下是一些解决方法:
def f(xs: List[Int]) = xs./:(0) _
def f(xs: List[Int]): ((Int, Int) => Int) => Int = (0 /: xs)
但我的问题主要是关于一般的正确语法。
答案 0 :(得分:2)
看起来像编译器错误。我已经在不同的scala版本和我得到的内容上测试了这个表达式:
def f(xs: List[Int]) = (0 /: xs) _
2.9.1.final
和2.8.2.final
的行为相同,但对于2.7.7.final
,它会触发不同的错误消息(Iterable
与TraversableOnes
),但我认为是因为旧版本中的集合库重新设计。
def f(xs: List[Int]) = (0 /: xs) _
<console>:4: error: missing arguments for method /: in trait Iterable;
follow this method with `_' if you want to treat it as a partially applied function
我在评论中提到的表达式对于不同的scala版本表现不同。
def f(xs: List[Int]): (Int, Int) => Int => Int = (0 /: xs)
scala 2.9.1.final:
found : (Int, Int) => Int => Int
required: (Int, Int) => Int => Int
确实令人困惑的编译器消息,绝对是一个错误。
scala 2.8.2.final:
found : => ((Int, Int) => Int) => Int
required: (Int, Int) => (Int) => Int
开始时奇怪的=>
与2.7.7相比。最终结果看起来像是回归。
scala 2.7.7.final:
found : ((Int, Int) => Int) => Int
required: (Int, Int) => (Int) => Int
found
似乎是对的,但代码仍无效。
我在scala bugtracker上搜索了类似的问题,但找不到合适的内容。认为这足以创建一张票(或两张?看起来这两个错误无关)。
答案 1 :(得分:2)
我刚刚解决了这个问题,但我还是无法检查它,因为它需要修改规范。
scala> def f(xs: List[Int]) = (0 /: xs) _
f: (xs: List[Int])(Int, Int) => Int => Int
scala> f(1 to 10 toList)
res0: (Int, Int) => Int => Int = <function1>
scala> res0(_ + _)
res1: Int = 55
问题在于,如果op是右关联的,则规范定义为“e1 op e2”{val x = e1; e2.op(x)}由于我不明白的原因,因为更简单的e2.op(e1)解决了这个问题,如https://issues.scala-lang.org/browse/SI-1980。我会询问。