2012-10-15 64 views
10

任何人都可以解释为什么我看到下面这个编译错误,当我忽略点符号的应用foldLeft功能?(2.9.2版本)为什么在foldLeft中留下点会导致编译错误?

scala> val l = List(1, 2, 3) 
res19: List[Int] = List(1 ,2 ,3) 

scala> l foldLeft(1)(_ * _) 
<console>:9: error: Int(1) does not take parameters 
        l foldLeft(1)(_ * _) 
            ^

scala> l.foldLeft(1)(_ * _) 
res27: Int = 6 

这没有按” t适用于其他高阶函数,如map这似乎不关心我是否提供点或不。

我不认为它的关联的事情,因为我不能只调用foldLeft(1)

回答

17

这是因为foldLeft是令行禁止。除了使用点符号,你也可以通过添加括号解决这个问题:

scala> (l foldLeft 1)(_ * _) 
res3: Int = 6 

噢 - 关于有关无法调用foldLeft(l)您的评论,你可以,但你需要部分地应用它像这样:

scala> (l foldLeft 1) _ 
res3: ((Int, Int) => Int) => Int = <function1> 
+0

谢谢建设性的说明,我的问题的完整答案在您对Regis的文章所做的第一条评论中,关于解析器如何攻击表达式。 – nsfyn55

3

省略点是可能的,因为Scala的为中间符号语法的支持,预计3个部分:

leftOperand operator rightOperand. 

但由于foldLeft有参数的两个列表,你最终用4份在句法层面:lfoldLeft(1)(_ * _)

哪些不适合缀表示法,因此错误。

+0

这对于了解中缀表示法是否有用可能是一个很好的经验法则,但我不确定它是否完全准确。可以使用中缀表示法调用'foldLeft'(如我之前的回答所示)。问题是解析器解析'l fold left(1)(_ * _)'为'l foldLeft((1)(_ * _))'而不是'(l foldLeft(1))(_ * _ )'。 –

+0

你的工作实际上证明了我的观点。您正在强制foldLeft的部分应用,以便有3个部分,这使中缀符号成为可能。结果是一个函数,你立即调用。 –

+0

对不起 - 这只是我的一部分,但错误不是由于中缀符号被编译器拒绝。这是由于编译器试图将'(_ * _)'应用于'(1)',而不能。 –

相关问题