Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing class for pattern matching

For example,

val list = List(1,2,3)
list match {
  case a :: b => 
  case _      => 
}

you can match head and tail of a List using :: or tokens of ParseResult using ~. What should I do to create class that can be matched like preceding classes?

UPD:

And have possibility to write:

case class @ ...
List(1,2,3,4) match {
  case 1 @ 2 @ 3 @ 4 => 
}
like image 657
Jeriho Avatar asked May 24 '10 20:05

Jeriho


2 Answers

There's not much to it. These two statements are equivalent:

case x :: xs =>
case ::(x, xs) =>

Say you want something to separate a list into odds and evens, and call it **. You could write the extractor like this:

object ** {
  def unapply(xs: List[Int]) = Some(xs partition (_ % 2 == 0))
}

scala> List(1,2,3) match {
     |   case evens ** odds => println("Evens: "+evens+"\nOdds: "+odds)
     | }
Evens: List(2)
Odds: List(1, 3)
like image 72
Daniel C. Sobral Avatar answered Sep 28 '22 09:09

Daniel C. Sobral


If you define your class as a case class it can be pattern-matched like this.

If you want to pattern-match on something other than the class's constructor, you can use extractors to define custom patterns.

like image 29
sepp2k Avatar answered Sep 28 '22 09:09

sepp2k