Pattern matching does not work

I wonder why this does not work:

def example(list: List[Int]) = list match { case Nil => println("Nil") case List(x) => println(x) } example(List(11, 3, -5, 5, 889, 955, 1024)) 

It says:

 scala.MatchError: List(11, 3, -5, 5, 889, 955, 1024) (of class scala.collection.immutable.$colon$colon) 
+4
source share
3 answers

This does not work because List(x) means a list with only one item. Check this:

 def example(list: List[Int]) = list match { case Nil => println("Nil") case List(x) => println("one element: " + x) case xs => println("more elements: " + xs) } example(List(11, 3, -5, 5, 889, 955, 1024)) //more elements: List(11, 3, -5, 5, 889, 955, 1024) example(List(5)) //one element: 5 
+15
source

Because List(x) only matches lists with one item. So

 def example(list: List[Int]) = list match { case Nil => println("Nil") case List(x) => println(x) } 

only works with lists of zero or one item.

+6
source

As other posters noted, List(x) only matches a list of 1 element.

However, there is syntax for matching multiple elements:

 def example(list: List[Int]) = list match { case Nil => println("Nil") case List(x @ _*) => println(x) } example(List(11, 3, -5, 5, 889, 955, 1024)) // Prints List(11, 3, -5, 5, 889, 955, 1024) 

This is a fun thing that makes a difference. _* corresponds to the repeated parameter, and x @ says: "Associate this with x ."

The same thing works with any pattern matching that can match repeating elements (e.g. Array(x @ _*) or Seq(x @ _*) ). List(x @ _*) may also correspond to empty lists, although in this case we have already matched Nil.

You can also use _* to match the "rest", as in:

 def example(list: List[Int]) = list match { case Nil => println("Nil") case List(x) => println(x) case List(x, xs @ _*) => println(x + " and then " + xs) } 
+2
source

Source: https://habr.com/ru/post/1492567/


All Articles