Scala中缀表示法

时间:2016-07-26 05:04:06

标签: 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$3: String) => x$3.toUpperCase()))(List.canBuildFrom[String]).filter(((x$4: String) => x$4.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))

而我得到编译器错误。

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

1 个答案:

答案 0 :(得分:2)

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

  

中缀运算符的优先级由运算符确定   第一个角色。下面按字母顺序递增字符列出   优先级,同一行上的字符具有相同的优先级   的优先级:

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

运营商的优先级和关联性决定了分组   表达式的一部分如下。

     
      
  • 如果表达式中有多个中缀操作,则运算符   具有更高优先级的绑定比具有更低的运算符更紧密绑定   优先。

  •   
  • 如果有连续的中缀操作   e0; op1; e1; op2… opn; en与运营商合作   op1,…,opnop1,…,opn具有相同的优先级,然后是所有这些运算符   必须具有相同的关联性。如果所有运营商都是   左关联,序列被解释为   (…(e0;op1;e1);op2…);opn;en。否则,如果   所有运算符都是右关联的,序列被解释为   e0;op1;(e1;op2;(…opn;en)…).

  •   
  • 后缀运算符的优先级始终低于中缀运算符。例如。   e1; op1; e2; op2总是相当于   (e1;op1;e2);op2
  •   

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

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

由于|的优先级低于&,因此最后调用它,然后&>>保持关联状态,以便从左到右调用它们。