Pregunta

Estoy trabajando en un DSL y me he encontrado con un problema al usar métodos como operadores infijos en una cadena.Intentaré explicarlo con algún código.Tengo un rasgo Term y clases de caso Literal y Variable extendiéndolo.Quiero construir una lista de instancias de términos usando algunos operadores.

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

Esperaría que esto fuera equivalente a foo.bar("x").-->(all), pero el intérprete parece verlo como foo.bar("x".-->(all)).

¿Fue útil?

Solución

Puede encontrar precedencia de operadores aquí:

Precedencia del operador en Scala

De acuerdo con la primera respuesta - tiene mayor prioridad en comparación con las letras.Entonces, los grupos de compiladores expresan como esta:

foo bar ("x" --> all)

Si reemplaza --> con algo de menor prioridad (por ejemplo, letras), entonces debería compilarse.Por ejemplo:

foo bar "x" to all

También puede elegir un operador de mayor prioridad en lugar de bar.Algo como ~~> lo hará, porque ~ es un carácter especial y tiene la máxima prioridad:

foo ~~> "x" --> all
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top