Scala 中缀表示法

Scala infix notation

这是我的代码...

val strings: Enumerator[String] = Enumerator("1","2","3","4")

//create am Enumeratee using the map method on Enumeratee

val toInt: Enumeratee[String,Int] = Enumeratee.map[String]{ 
    (s: String) => s.toInt 
}
val toSelf: Enumeratee[String,String] = Enumeratee.map[String]{ 
    (s: String) => s 
}
List("Mary", "Paul") map (_.toUpperCase) filter (_.length > 5)

val r1 = strings |>> (toSelf &>> (toInt &>> sum))
val r2 = strings |>> toSelf &>> (toInt &>> sum)
val r3 = strings |>> toSelf &>> toInt &>> sum // does not compile

val foo1 = strings &> toInt |>> sum
val foo2 = strings &> (toInt |>> sum) // does not compile
val foo3 = (strings &> toInt) |>> sum

符号|>>、&>>。 &> 是方法。我对编译器在它们周围加上括号的方式感到困惑。在行中:

List("Mary", "Paul") map (_.toUpperCase) filter (_.length > 5)

编译器是这样插入括号的:

((List("Mary", "Paul") map (_.toUpperCase))) filter (_.length > 5)

实际上它编译为:

List("Mary", "Paul").map(((x: String) => x.toUpperCase()))(List.canBuildFrom[String]).filter(((x: String) => x.length().>(5)))

在随后的例子中:

strings |>> toSelf &>> (toInt &>> sum)

编译器是这样插入括号的:

strings |>> (toSelf &>> (toInt &>> sum))

实际上它编译为:

strings.|>> (toSelf.&>> (toInt.&>>(sum)))

有时编译器似乎是从右到左插入括号(第二个示例),有时编译器似乎是从左到右插入括号(第一个示例)。有时,比如在

val r3 = strings |>> toSelf &>> toInt &>> sum

我希望它像

一样插入括号
val r3 = strings |>> (toSelf &>> (toInt &>> sum))

相反,我收到编译器错误。

有人可以解释一下空格分隔方法的括号插入规则吗?

infix notation have a precedence 中的操作定义给它们,如规范中所述:

The precedence of an infix operator is determined by the operator's first character. Characters are listed below in increasing order of precedence, with characters on the same line having the same precedence:

(all letters)
|
^
&
= !
< >
:
+ -
* / %
(all other special characters)

Precedence and associativity of operators determine the grouping of parts of an expression as follows.

  • If there are several infix operations in an expression, then operators with higher precedence bind more closely than operators with lower precedence.

  • If there are consecutive infix operations e0; op1; e1; op2… opn; en with operators op1,…,opnop1,…,opn of the same precedence, then all these operators must have the same associativity. If all operators are left-associative, the sequence is interpreted as (…(e0;op1;e1);op2…);opn;en. Otherwise, if all operators are right-associative, the sequence is interpreted as e0;op1;(e1;op2;(…opn;en)…).

  • Postfix operators always have lower precedence than infix operators. E.g. e1; op1; e2; op2 is always equivalent to (e1;op1;e2);op2

根据规范,您的第二个表达式应该是:

strings.|>>((toSelf.&>>toInt).&>>(sum)))

由于 | 的优先级低于 &,它被最后调用,然后 &>> 是左关联的,因此它们是从左到右调用的。