Scala pattern matching extractors right associativity

I am currently playing around with the Scala pattern. What I know so far is that an extractor named as an operator becomes left associative, and an extractor named as a method or type is correct associative.

My current approach looks something like this:

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

      

This is somewhat inconvenient as it requires me to write my matches in reverse order or match them to reverse due to the correct associativity. I would prefer to write something like this:

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

      

Is there a way to keep some readable name for the extractor and make it left associative?

Thanks in advance.

+3


source to share


2 answers


You need to end your class name :

.
From Scala Specifications (Infix Operations, 6.12.3):

The operator associativity is determined by the operators of the latter character. Operators ending in a colon ': are right-associative. All other operators are left-associative.

Thus:



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)

      

Unfortunately, you need to use backticks as Foo:

it is not a valid identifier.

+5


source


I'm not sure if I am correct, but I think you are asking for something like this:



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

      

0


source







All Articles