當你忽略圓點和圓括號時,你會使用所謂的中綴表示法。它允許你寫a + b
而不是a.+(b)
。這裏有一個重要的原則是,如果調用的形式object method paramlist
這是隻允許(見SLS 6.12.3):
The right-hand operand of a left-associative operator may consist of several arguments enclosed in parentheses, e.g. e op (e 1 , ... , e n)
. This expression is then interpreted as e.op(e 1 , ... , e n)
.
foldLeft
不適合這種形式,它使用object method paramlist1 paramlist2
。因此,如果你寫這在操作符號編譯器將其視爲object.method(paramlist1).paramlist2
(如SLS 6.12.2描述):
A postfix operator can be an arbitrary identifier. The postfix operation e op
is interpreted as e.op
.
但是這裏應用的另一個規則:(SLS 6.6)功能的應用。
An application f(e 1 , ... , e m)
applies the function f
to the argument expressions e 1 , ... , e m
.
[...]
If f
has some value type, the application is taken to be equivalent to f.apply(e 1 , ... , e m)
, i.e. the application of an apply method defined by f
.
這裏,我們去:
scala> { (a, x) => a + x }
<console>:12: error: missing parameter type
{ (a, x) => a + x }
^
<console>:12: error: missing parameter type
{ (a, x) => a + x }
^
這僅僅是一個函數字面是錯過它的類型參數。如果再加上他們的一切編譯罰款:
scala> { (a: String, x: Wrapper[String]) => a + x }
res6: (String, Wrapper[String]) => String = <function2>
編譯器只用於有關上述功能的應用規則:
scala> "" { (a: String, x: Wrapper[String]) => a + x }
<console>:13: error: type mismatch;
found : (String, Wrapper[String]) => String
required: Int
"" { (a: String, x: Wrapper[String]) => a + x }
^
scala> "" apply { (a: String, x: Wrapper[String]) => a + x }
<console>:13: error: type mismatch;
found : (String, Wrapper[String]) => String
required: Int
"" apply { (a: String, x: Wrapper[String]) => a + x }
^
因此,你的代碼被解釋爲
scala> xs foldLeft ("").apply{ (a: String, x: Wrapper[String]) => a + x }
<console>:14: error: type mismatch;
found : (String, Wrapper[String]) => String
required: Int
xs foldLeft ("").apply{ (a: String, x: Wrapper[String]) => a + x }
^
但爲什麼它是否應用了函數應用程序規則?也可以將函數文字作爲後綴運算符應用。要了解爲什麼我們會看到顯示的錯誤消息,需要查看SLS Scala Syntax Summary。在那裏,我們可以看到如下:
InfixExpr ::= PrefixExpr
| InfixExpr id [nl] InfixExpr
PrefixExpr ::= [‘-’ | ‘+’ | ‘~’ | ‘!’] SimpleExpr
SimpleExpr ::= ‘new’ (ClassTemplate | TemplateBody)
| BlockExpr
| SimpleExpr1 [‘_’]
SimpleExpr1 ::= Literal
| Path
| ‘_’
| ‘(’ [Exprs] ‘)’
| SimpleExpr ‘.’ id
| SimpleExpr TypeArgs
| SimpleExpr1 ArgumentExprs
| XmlExpr
Exprs ::= Expr {‘,’ Expr}
ArgumentExprs ::= ‘(’ [Exprs] ‘)’
| ‘(’ [Exprs ‘,’] PostfixExpr ‘:’ ‘_’ ‘*’ ‘)’
| [nl] BlockExpr
從描述的部分上面我們知道,ArgumentExprs
描述的功能應用,同時InfixExpr
描述中綴表達式。由於EBNF的規則,最高規則的優先級最低。而且由於前者的規則由後者調用,這意味着函數文字在中綴表達式之前應用,因此是錯誤消息。
謝謝您的詳細回覆,僅以您的最後一個示例爲理由,但SLS的摘錄添加了更多上下文。 – jroesch 2013-03-25 01:22:27