2011-05-05 13 views
7

Pracuję nad DSL i mam problem z wykorzystaniem metod jako operatorów infiksów w łańcuchu. Po prostu spróbuję wyjaśnić to za pomocą jakiegoś kodu. Mam cechy Term i klasy przypadków Literal i. Chcę utworzyć listę wystąpień terminowych za pomocą niektórych operatorów.Dlaczego nie mogę połączyć kilku wywołań metod Scala

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

Spodziewam się, że będzie to równoznaczne z foo.bar("x").-->(all) ale interpreter zdaje się widzieć go jako foo.bar("x".-->(all)).

Odpowiedz

14

można znaleźć pierwszeństwo operatora tutaj:

Operator precedence in Scala

Według pierwszej odpowiedzi - ma wyższy priorytet w stosunku do liter. Więc kompilator grupy wyrażenie tak:

foo bar ("x" --> all) 

Jeśli będzie zastąpić --> z czymś niższym priorytecie (na przykład litery), a następnie należy go skompilować. Na przykład:

foo bar "x" to all 

Można również wybrać wyższy priorytet operatora zamiast bar. Coś jak ~~> to zrobi, bo ~ jest wyjątkowy charakter i ma najwyższy priorytet:

foo ~~> "x" --> all 
+0

Dzięki! Sądzę, że widząc operatorów jako metody, zapomniałem, że mogą mieć pierwszeństwo. –

Powiązane problemy