Consider the following piece of Scala code:
type i = Integer
val s1: List[Any] = List(1, "two")
s1 collect { case e: i => e } foreach (e => println(s"$e, ${e.getClass}"))
val s2: List[List[Any]] = List(List(1, "two"), List("one", 2))
s2 collect { case e: List[i] => e } foreach (e => println(s"$e, ${e.getClass}"))
val s3: List[List[Any]] = List(List(1, "two"), List("one", 2))
s3 collect { case e: List[`i`] => e } foreach (e => println(s"$e, ${e.getClass}"))
s1 filters on i so it only prints the elements of type i, in our case Integer:
1, class java.lang.Integer
s2 defines a new type variable called i (which shadows the original i) and assigns to it the current type of e. It matches all the elements in s2, so it outputs:
List(1, two), class scala.collection.immutable.$colon$colon
List(one, 2), class scala.collection.immutable.$colon$colon
s3 tries to only filter on elements of type List[Integer], since it treats i as a stable identifier, but because of erasure, this ends up returning the whole list:
List(1, two), class scala.collection.immutable.$colon$colon
List(one, 2), class scala.collection.immutable.$colon$colon
Now, what I don't understand is why treat i differently in the s1 and s2 cases. In one situation it refers to the already defined type variable, but in the other situation, it creates a new type variable.
It's type erasure, and nothing to do with the i alias, or the stability thereof
(incidentally, you really shouldn't use lower case type names like this!)
If you substitute the alias and run in a REPL with the -unchecked flag, you get:
val s3: List[List[Any]] = List(List(1, "two"), List("one", 2))
s3: List[List[Any]] = List(List(1, two), List(one, 2))
s3 collect { case e: List[Integer] => e } foreach (e => println(s"$e, ${e.getClass}"))
<console>:9: warning: non-variable type argument Integer in type pattern List[Integer] is unchecked since it is eliminated by erasure
s3 collect { case e: List[Integer] => e } foreach (e => println(s"$e,${e.getClass}"))
^
List(1, two), class scala.collection.immutable.$colon$colon
List(one, 2), class scala.collection.immutable.$colon$colon
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