Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mixing typed matches with sequence matcher gives out strange behaviour in Scala

I'm trying to figure out what's going on on this piece of code, trying to figure out if there is something I don't understand or if it is a compiler bug or unintuitive spec, let's define these two almost identical functions:

def typeErause1(a: Any) = a match {
    case x: List[String] => "stringlists"
    case _ => "uh?"
}
def typeErause2(a: Any) = a match {
    case List(_, _) => "2lists"
    case x: List[String] => "stringlists"
    case _ => "uh?"
}

now if I call typeErause1(List(2,5,6)) I get "stringlists" because even if it is actually List[Int] with type erasure it is not able to tell the difference. But strangely if I call typeErause2(List(2,5,6)) I get "uh?" and I don't understand why it is not matching List[String] like it did before. If I use List[_] instead on the second function it is able to match it correctly which makes me think this is a bug in scalac.

I'm using Scala 2.9.1

like image 334
ilcavero Avatar asked Apr 08 '12 01:04

ilcavero


1 Answers

It's a bug in the matcher ;) The pattern matcher is being (has been?) rewritten for 2.10

I just checked with the latest nightly and your code works as expected:

Welcome to Scala version 2.10.0-20120426-131046-b1aaf74775 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_31).
Type in expressions to have them evaluated.
Type :help for more information.

scala> def typeErause1(a: Any) = a match {
     |     case x: List[String] => "stringlists"
     |     case _ => "uh?"
     | }
warning: there were 2 unchecked warnings; re-run with -unchecked for details
typeErause1: (a: Any)String

scala> def typeErause2(a: Any) = a match {
     |     case List(_, _) => "2lists"
     |     case x: List[String] => "stringlists"
     |     case _ => "uh?"
     | }
warning: there were 3 unchecked warnings; re-run with -unchecked for details
typeErause2: (a: Any)String

scala> typeErause1(List(2,5,6))
res0: String = stringlists

scala> typeErause2(List(2,5,6)) 
res1: String = stringlists
like image 177
rxg Avatar answered Oct 16 '22 00:10

rxg