Why can't I chain several Scala infix method calls
Asked Answered
E

1

8

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

Eileneeilis answered 5/5, 2011 at 21:1 Comment(0)
A
17

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
Anomalistic answered 5/5, 2011 at 21:21 Comment(1)
Thanks! I guess seeing the operators as methods had me forget that they can have precedence.Eileneeilis

© 2022 - 2024 — McMap. All rights reserved.