2015-06-02 2 views
3

Я сейчас играю с совпадением шаблонов Scala. То, что я знаю до сих пор, заключается в том, что экстрактор, названный как оператор, получает ассоциативную ассоциацию, а экстрактор, названный как метод или тип, является правильным ассоциативным.Scala pattern matching extractors right ассоциативность

Моего текущий подход выглядит следующим образом:

object Foo { 
    def unapply(tokens: Seq[String]): Option[(Seq[String], String)] = // do something 
} 

// ... 

object Main extends App { 
    Seq("hi", "bye") match { 
    case xs Foo foo2 Foo foo1 => // do something with result 
    case _ => // handle error 
    } 
} 

Это несколько unpleasuring, поскольку это требует от меня, чтобы написать мои матчи назад или соответствие их обратными из-за правую ассоциативность. Я предпочел бы, если бы я мог бы написать что-то вроде этого:

object Foo { 
    def unapply(tokens: Seq[String]): Option[(String, Seq[String])] = // do something 
} 

// ... 

object Main extends App { 
    Seq("hi", "bye") match { 
    case foo1 Foo foo2 xs => // do something with result 
    case _ => // handle error 
    } 
} 

Есть ли способ, чтобы сохранить некоторое читаемое имя экстрактора и сделать его левоассоциативен?

Заранее спасибо.

ответ

5

Вы должны закончить свое имя класса с :.
Из Scala Specifications (Инфиксные операций, 6.12.3):

ассоциативность оператора определяется по последнему характер оператора. Операторы, заканчивающиеся на двоеточие ':', являются право-ассоциативными. Все другие операторы являются лево-ассоциативными.

Таким образом:

scala> object `Foo:` { 
     def unapply(tokens: Seq[String]): Option[(String, Seq[String])] = 
      Some((tokens.head, tokens.tail)) 
     } 
defined object Foo$colon 

scala> Seq("hi", "bye", "world") match { 
     case foo1 `Foo:` foo2 `Foo:` foo3 => println(s"$foo1 $foo2 $foo3") 
     } 
hi bye List(world) 

К сожалению, вам нужно использовать кавычку, поскольку Foo: не является допустимым идентификатором.

+1

Ах спасибо, это было то, что я искал! И backticks - ничто, у меня нет проблемы с тем, пока само правило все еще доступно для чтения. – bash0r

0

Я не уверен, если я получаю вопрос правильно, но я думаю, что вы просите что-то вроде этого:

object Foo { 
    def unapply(tokens: Seq[String]): Option[(String, Seq[String])] = 
     Some((tokens.head, tokens.tail)) 
    } 

// ... 

object Main extends App { 
    Seq("hi", "bye") match { 
    case foo1 Foo foo2 => println(s">> $foo1 $foo2") 
    case _ => println("error") // handle error 
    } 
} 
+1

Это поведение, которое я хочу. Единственная проблема заключается в том, что она начинает терпеть неудачу, как только вы ее связываете, потому что Foo является правильным ассоциативным. – bash0r