2016-07-26 5 views
2

Вот мой код ...Scala инфикс обозначения

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) 

Компилятор - это inserti нг скобки так:

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

В действительности он компилирует:

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

Иногда кажется, что компилятор вставляет скобку справа налево (второй пример), а иногда кажется, компилятор вставляет скобки слева направо (первый пример). Иногда, как в

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

Я ожидаю, что это вставить скобку как

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

и вместо этого я получаю ошибку компиляции.

Может кто-нибудь, пожалуйста, объясните правила вставки в скобки для методов с пробелами?

ответ

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)…).

  • Операторы Postfix всегда имеют более низкий приоритет, чем операторы infix. Например. e1; op1; e2; op2 всегда эквивалентна (e1;op1;e2);op2

Согласно спецификации, ваше второе выражение должно быть:

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

Поскольку | имеет меньший приоритет, чем &, она вызывается последним, а затем &>> оставлены ассоциативными, поэтому они вызываются слева направо.

+0

Метод '& >>' имеет более высокий приоритет, чем '| >>', а '& >>' остается ассоциативным, поэтому 'stringings >> >> toSelf & >> toInt & >> sum' интерпретируется как' strings | >> ((toSelf & >> toInt) & >> sum) '. –

+1

@JohnReed Да, вот что я имел в виду. Похоже, я испортил круглую скобку. Исправлена. –

 Смежные вопросы

  • Нет связанных вопросов^_^