2011-05-05 10 views
7

Estoy trabajando en una DSL y he tenido un problema con el uso de métodos como operadores infijo en una cadena. Voy a tratar de explicarlo con un código. Tengo un rasgo Term y clases de casos Literal y Variable extendiéndolo. Quiero construir una lista de instancias de términos usando algunos operadores.¿Por qué no puedo encadenar varias llamadas al método infijo Scala?

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

Yo esperaría que esto sería equivalente a foo.bar("x").-->(all) pero el intérprete parece verlo como foo.bar("x".-->(all)).

Respuesta

14

Usted puede encontrar precedencia operador aquí:

Operator precedence in Scala

De acuerdo con la primera respuesta - tiene mayor prioridad en comparación con las cartas. grupos expresión tan compilador de la siguiente manera:

foo bar ("x" --> all) 

Si va a reemplazar --> con algo de menor prioridad (por ejemplo letras), entonces se debe compilar. Por ejemplo:

foo bar "x" to all 

También puede elegir más alta prioridad del operador en lugar de bar. Algo así como ~~> lo hará, porque es ~ carácter especial y tiene la más alta prioridad:

foo ~~> "x" --> all 
+0

Gracias! Supongo que ver a los operadores como métodos me hizo olvidar que pueden tener prioridad. –

Cuestiones relacionadas