ドットと括弧を省略すると、いわゆる中置記法が使用されます。a + b
の代わりに書くことができますa.+(b)
。ここでの重要なルールは、呼び出しが次の形式の場合にのみ許可されるということですobject method paramlist
( SLS 6.12.3を参照)。
左結合演算子の右側のオペランドは、括弧で囲まれた複数の引数で構成される場合がありますe op (e 1 , ... , e n )
。この式は として解釈されe.op(e 1 , ... , e n )
ます。
foldLeft
はこの形式に適合しないため、 を使用しますobject method paramlist1 paramlist2
。したがって、これを演算子表記で記述すると、コンパイラは次のように扱います( SLS 6.12.2object.method(paramlist1).paramlist2
で説明されているように)。
後置演算子は、任意の識別子にすることができます。後置操作e op
は として解釈されe.op
ます。
ただし、ここで適用される別のルールがあります: Function Applications ( SLS 6.6 )。
アプリケーションf(e 1 , ... , e m)
は、関数f
を引数式に
適用しますe 1 , ... , e m
。
[...]
が何らかの値型を持っている場合f
、アプリケーションは と等価であると見なされますf.apply(e 1 , ... , e m)
。つまり、 によって定義された apply メソッドのアプリケーションです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の規則により、最上位の規則の優先順位が最も低くなります。また、前者の規則は後者の規則によって呼び出されるため、関数リテラルが中置式の前に適用されることを意味し、エラー メッセージが表示されます。