Почему я не могу связать несколько вызовов инфиксных методов Scala - PullRequest
8 голосов
/ 06 мая 2011

Я работаю над DSL и столкнулся с проблемой использования методов в качестве инфиксных операторов в цепочке. Я просто попытаюсь объяснить это с помощью некоторого кода. У меня есть черта Term и классы дел Literal и Variable, расширяющие ее. Я хочу составить список экземпляров терминов, используя некоторые операторы.

case class Expr(val terms: List[Term]) {
 def +(v: String) = Expr(Literal(v) :: terms)
 def -->(func: List[String] => List[String]) = terms match {
  case Literal(v) :: ts => Expr(Variable(v, func) :: ts)
  case _ => throw new Exception("Can only apply function on literal")
 }
}

object foo {
 def bar(name: String) = Expr(Literal(name) :: Nil)
}

// some functions
val one = ... 
val all = ...

// works
foo bar "x"        
// res1: Expr = Expr(List(Literal(x)))

// works not
foo bar "x" --> all
// error: value --> is not a member of java.lang.String

// works
(foo bar "x") --> all 
// res1: Expr = Expr(List(Variable(x,<function1>)))

Я ожидаю, что это будет эквивалентно foo.bar("x").-->(all), но интерпретатор, похоже, видит это как foo.bar("x".-->(all)).

1 Ответ

16 голосов
/ 06 мая 2011

Вы можете найти приоритет оператора здесь:

Приоритет оператора в Scala

Согласно первому ответу - имеет более высокий приоритет по сравнению с буквами. Таким образом, компилятор группирует выражение так:

foo bar ("x" --> all)

Если вы замените --> на что-то с более низким приоритетом (например, буквы), то оно должно скомпилироваться. Например:

foo bar "x" to all

Вы также можете выбрать оператор с более высоким приоритетом вместо bar. Что-то вроде ~~> сделает это, потому что ~ является специальным символом и имеет наивысший приоритет:

foo ~~> "x" --> all
...