I have a little problem in pattern matching an object in Scala when it is parameterized with a fully qualified class name. This is based on Scala 2.9.0.1. Anyone knows what's wrong with this code?
scala> "foo" match {
| case y : Seq[Integer] =>
| case y : Seq[java.lang.Integer] =>
<console>:3: error: ']' expected but '.' found.
case y : Seq[java.lang.Integer] =>
Why does the first version work, but the latter fail? The problem only seems to occur when a fully qualified classname is used for the parameterization.
From the Scala Language Specification, section 8.1 Patterns, the identifier after the : needs to be what is referred to as a Type Pattern, defined in Section 8.2:
Type patterns consist of types, type variables, and wildcards. A type pattern T is of one of the following forms:
...
A parameterized type pattern T [a(1), . . . , a(n)], where the a(i) are type variable patterns or wildcards _. This type pattern matches all values which match T for some arbitrary instantiation of the type variables and wildcards. The bounds or alias type of these type variable are determined as described in (§8.3).
...
A type variable pattern is a simple identifier which starts with a lower case letter. However, the predefined primitive type aliases unit, boolean, byte, short, char, int, long, float, and double are not classified as type variable patterns.
So, syntactically, you can't use a fully qualified class as a type variable pattern IN THIS POSITION. You can however, use a type alias, so:
type JavaInt = java.lang.Integer
List(new java.lang.Integer(5)) match {
case y: Seq[JavaInt] => 6
case _ => 7
}
will return 6 as expected. The problem is that as Alan Burlison points out, the following also returns 6:
List("foobar") match {
case y: Seq[JavaInt] => 6
case _ => 7
}
because the type is being erased. You can see this by running the REPL, or scalac with the -unchecked option.
In fact your first example doesn't work either. If you run the REPL with -unchecked, you'll see the following error:
warning: non variable type-argument Integer in type pattern Seq[Integer] is unchecked since it is eliminated by erasure
So you can't actually do what you are trying to do - at run-time there's no difference between a List[Integer] and a List[AnythingElse], so you can't pattern-match on it. You might be able to do this with a Manifest, see http://ofps.oreilly.com/titles/9780596155957/ScalasTypeSystem.html#Manifests and http://www.scala-blogs.org/2008/10/manifests-reified-types.html
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