Pergunta

Estou trabalhando em uma DSL e tive um problema com o uso de métodos como operadores infixos em uma cadeia.Vou apenas tentar explicar com algum código.Eu tenho um Term de traço e classes de caso Literal e Variable estendendo-o.Quero construir uma lista de instâncias de termos usando alguns 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>)))

Eu esperaria que isso fosse equivalente a foo.bar("x").-->(all), mas o interpretador parece vê-lo como foo.bar("x".-->(all)).

Foi útil?

Solução

Você pode encontrar a precedência do operador aqui:

Precedência do operador em Scala

De acordo com a primeira resposta, - tem maior prioridade em comparação com as letras.Portanto, o compilador agrupa expressões como esta:

foo bar ("x" --> all)

Se você for substituir --> por algo de menor prioridade (por exemplo, letras), ele deve ser compilado.Por exemplo:

foo bar "x" to all

Você também pode escolher o operador de prioridade mais alta em vez do bar.Algo como ~~> fará isso, porque ~ é um caractere especial e tem a prioridade mais alta:

foo ~~> "x" --> all
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top