Frage

Ich arbeite an einem DSL und habe ein Problem mit der Verwendung von Methoden als Infix-Operatoren in einer Kette.Ich werde nur versuchen, es mit etwas Code zu erklären.Ich habe ein Merkmal Term und Fallklassen Literal und Variable, die es erweitern.Ich möchte mit einigen Operatoren eine Liste von Terminstanzen erstellen.

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

Ich würde erwarten, dass dies dem foo.bar("x").-->(all) entspricht, aber der Interpreter scheint ihn als foo.bar("x".-->(all)) zu betrachten.

War es hilfreich?

Lösung

Hier finden Sie die Operator-Priorität :

Operator-Vorrang in Scala

Nach der ersten Antwort hat - eine höhere Priorität als Buchstaben.Der Compiler gruppiert den Ausdruck also wie folgt:

foo bar ("x" --> all)

Wenn Sie --> durch etwas mit niedrigerer Priorität (z. B. Buchstaben) ersetzen, sollte es kompiliert werden.Zum Beispiel:

foo bar "x" to all

Sie können auch einen Operator mit höherer Priorität anstelle von bar wählen.So etwas wie ~~> wird es tun, weil ~ ein Sonderzeichen ist und höchste Priorität hat:

foo ~~> "x" --> all

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top