I have the following code which recursively operates on each element within a List
def doMatch(list: List[Int]): Unit = list match { case last :: Nil => println("Final element.") case head :: tail => println("Recursing..."); doMatch(tail) }
Now, ignoring that this functionality is available through filter() and foreach(), this works just fine. However, if I try to change it to accept any Seq[Int], I run into problems:
Here is how I think the code should look, except it doesn't work:
def doMatch(seq: Seq[Int]): Unit = seq match { case last +: Seq() => println("Final element.") case head +: tail => println("Recursing..."); doMatch(tail) }
Edit: So many good answers! I'm accepting agilesteel's answer as his was the first that noted that :: isn't an operator in my example, but a case class and hence the difference.
A pattern match includes a sequence of alternatives, each starting with the keyword case. Each alternative includes a pattern and one or more expressions, which will be evaluated if the pattern matches. An arrow symbol => separates the pattern from the expressions.
Notes. Scala's pattern matching statement is most useful for matching on algebraic types expressed via case classes. Scala also allows the definition of patterns independently of case classes, using unapply methods in extractor objects.
Pattern matching is a way of checking the given sequence of tokens for the presence of the specific pattern. It is the most widely used feature in Scala. It is a technique for checking a value against a pattern. It is similar to the switch statement of Java and C.
Case classes are Scala's way to allow pattern matching on objects without requiring a large amount of boilerplate. In the common case, all you need to do is add a single case keyword to each class that you want to be pattern matchable.
As of the ides of March 2012, this works in 2.10+:
def doMatch(seq: Seq[Int]): Unit = seq match { case last +: Seq() => println("Final element.") case head +: tail => println("Recursing..."); doMatch(tail) } //> doMatch: (seq: Seq[Int])Unit doMatch(List(1, 2)) //> Recursing... //| Final element.
More generally, two different head/tail and init/last decomposition objects mirroring append/prepend were added for Seq
in SeqExtractors:
List(1, 2) match { case init :+ last => last } //> res0: Int = 2 List(1, 2) match { case head +: tail => tail } //> res1: List[Int] = List(2) Vector(1, 2) match { case init :+ last => last } //> res2: Int = 2 Vector(1, 2) match { case head +: tail => tail } //> res3: scala.collection.immutable.Vector[Int] = Vector(2)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With