5

换句话说,这有什么不应该编译的充分理由吗?

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)

但我的问题主要是关于一般的正确语法。

4

2 回答 2

2

看起来像一个编译器错误。我已经在不同的 scala 版本上测试了这个表达式以及我得到了什么:

def f(xs: List[Int]) = (0 /: xs) _

它的行为相同2.9.1.final2.8.2.final2.7.7.final它会触发不同的错误消息(Iterablevs. 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)

斯卡拉2.9.1.final:

 found   : (Int, Int) => Int => Int
 required: (Int, Int) => Int => Int

真正令人困惑的编译器消息,绝对是一个错误。

斯卡拉2.8.2.final:

 found   : => ((Int, Int) => Int) => Int
 required: (Int, Int) => (Int) => Int

一开始很奇怪=>,与 2.7.7.final 相比,结果看起来像是回归。

斯卡拉2.7.7.final:

 found   : ((Int, Int) => Int) => Int
 required: (Int, Int) => (Int) => Int

found看似正确,但代码仍然无法正常工作。

我在scala bugtracker上搜索了类似的问题,但找不到任何合适的东西。认为创建一张票就足够了(或两张?看起来这两个错误不相关)。

于 2011-10-12T16:10:59.227 回答
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。我会进行查询。

于 2011-10-14T05:04:28.147 回答