Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding pattern matching on lists

I've been playing around with Extractors lately and was wondering how the List extractors work especially this:

List(1, 2, 3) match {
  case x :: y :: z :: Nil => x + y + z // case ::(x, ::(y, ::(z , Nil)))
}

Ok :: is used in the pattern, so I guess that the compiler now looks up the unapply method in the ::-Object. So tried this:

scala> (::).unapply(::(1, ::(2, Nil)))
res3: Option[(Int, List[Int])] = Some((1,List(2)))

Nice that works. However this does not:

scala> (::).unapply(List(1,2,3))      
<console>:6: error: type mismatch;
 found   : List[Int]
 required: scala.collection.immutable.::[?]
       (::).unapply(List(1,2,3))

while this does:

scala> List.unapplySeq(List(1,2,3))
res5: Some[List[Int]] = Some(List(1, 2, 3))

Actually I'm a little puzzled at the moment. How does the compiler choose the right implementation of unapply here.

like image 271
raichoo Avatar asked Feb 28 '11 20:02

raichoo


People also ask

How do you explain pattern matching?

Pattern matching is an algorithmic task that finds pre-determined patterns among sequences of raw data or processed tokens. In contrast to pattern recognition, this task can only make exact matches from an existing database and won't discover new patterns.

What is pattern matching give an example?

For example, x* matches any number of x characters, [0-9]* matches any number of digits, and . * matches any number of anything. A regular expression pattern match succeeds if the pattern matches anywhere in the value being tested.

How do you match a pattern to a list in Python?

Method : Using join regex + loop + re.match() In this, we create a new regex string by joining all the regex list and then match the string against it to check for match using match() with any of the element of regex list.

Why ++ is not allowed in pattern matching?

You can only pattern-match on data constructors, and ++ is a function, not a data constructor. Data constructors are persistent; a value like 'c':[] cannot be simplified further, because it is a fundamental value of type [Char] .


1 Answers

Match is basically doing the following:

(::).unapply(List[Int](1,2,3).asInstanceOf[::[Int]])

once it knows that it's safe (because List(1,2,3).isInstanceOf[::[Int]] is true).

like image 179
Rex Kerr Avatar answered Sep 23 '22 15:09

Rex Kerr