Search code examples
scalatype-parameter

How to determine subtype of a type parameter in Scala?


class S
class A extends S
class B extends S

class ClassWithTypeParameter[+T]

val a: ClassWithTypeParameter[S] = new ClassWithTypeParameter[A]

How can one determine the type of the subclass used for the type parameter of value a ?


Solution

  • You cannot because of type erasure. However, I would argue that your attempt to do this is formed from a mis-understanding.

    • The point of a type system is so that the compiler can reason more powerfully about the correctness of your program.
    • In a static type system, each reference has a type which cannot be changed

    In your program, there is one reference, a and the type of this reference is ClassWithTypeParameter[S]. That. Is. All. The compiler can know what can be done with this reference. The types are there purely for the compiler. The fact that, at runtime, a was assigned to a value which was a ClassWithTypeParameter[A] is irrelevant.


    One possible way of doing this to some approximation (limited by erasure) is to use manifests (called something else in 2.10):

    class ClassWithTypeParameter[+T: Manifest] { def erasure = manifest[T].erasure }
    

    Then you can call erasure which will get you a java.lang.Class back. As I said, this is limited. A class is not the same thing as a type and there is no way to distinguish, for example, ClassWithTypeParameter[List[Int]] from ClassWithTypeParameter[List[Double]]