I am working on a DSL and I've run into a problem with using methods as infix operators in a chain. I'll just try to explain it with some code. I have a trait Term
and case classes Literal
and Variable
extending it. I want to construct a list of term instances using some operators.
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>)))
I would expect that this would be equivalent to foo.bar("x").-->(all)
but the interpreter seems to see it as foo.bar("x".-->(all))
.
You can find operator precedence here:
Operator precedence in Scala
According to first answer -
has higher priority compared to letters. So compiler groups expression like this:
foo bar ("x" --> all)
If you will replace -->
with something of lower priority (e.g. letters), then it should compile. For example:
foo bar "x" to all
You can also choose higher priority operator instead of bar
. Something like ~~>
will do it, because ~
is special character and it has highest priority:
foo ~~> "x" --> all
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With