Reputation: 131
I want to be able to assert the type of a parameterized List in Scala. For e.g. I have the following types:
class Animal
class Cat extends Animal
class Dog extends Animal
And I instantiate lists as follows:
val l1 = List(new Cat())
val l2 = List(new Dog())
val m = l1 ::: l2
When I try to assert the type of list m
using the scalatest
Matchers, I am only able to assert the generic type, not the parameterized type.
import org.scalatest.Matchers._
m shouldBe a [List[_]]
What I actually want to do is to assert that m
is of type List[Animal]
and NOT of type List[Cat]
or List[Dog]
Is there any way I can do that?
Upvotes: 1
Views: 517
Reputation: 4585
Type erasure will prevent you from checking the type parameter at runtime. This is because any List[T]
becomes a List[Any]
at runtime (the actual value of T
is "erased").
However, as pointed out by others, the unit test you are writing is not needed because the compiler will automatically infer the type of m
to be List[Animal]
. This is because List
is declared as covariant (the +
in the List[+T]
definition).
See this answer for more details about covariance.
Upvotes: 4
Reputation: 125
You can't assert the actual type parameter in run time because of type erasure. And even if you circumvented the type erasure with somethinglike new MyList[Cat]{/** saves the actual type parameter in anonymous class definition */}
it would make little sense since List[Cat]
IS actually a List[Animal]
in Scala.
Upvotes: 4