Given a class definition with bound type parameter Animal[A <: String]
it seems that the Scala compiler does not infer B <: String
from Animal[B]
. Is the inference allowed? How to help the compiler to do the inference?
Below is a concrete example with case classes where the lack of this inference is a problem.
Consider the following case class hierarchy:
sealed trait Person[+T <: Person[T]]
case class Student() extends Person[Student]
case class Professor() extends Person[Professor]
I need to define a case class University
which I can instantiate with a variable of type Person[_]
, for example val p: Person[_] = Student()
. I thought this would work with the following definition:
case class University(p: Person[_])
But this fails compiling with the error:
type arguments [Any] do not conform to trait Person's type parameter bounds [+T <: Person[T]]
If I bind the type parameter of the case class University
it compiles (it also compiles with unbounded parameters if i drop the case
keyword but this is not an option in my case):
case class BoundUniversity[P <: Person[P]](p: Person[P])
But this parametrized version cannot be instantiated with an unbounded variable of type Person[_]
:
val p: Person[_] = Student()
BoundUniversity(p)
fails compiling with:
inferred type arguments [_$1] do not conform to method apply's type parameter bounds [P <: Person[P]]
The same error happens for a method with a bound argument like:
def general[P <: Person[P]](p: P) = println(p)
so this is not specific to class constructors.
Two questions:
The type
Person
is defined with parameter boundsPerson[+T <: Person[T]]
, so that each instance of this type is insured to respect those bounds:val p: Person[P]
implies thatP <: Person[P]
; or am I missing something? So how can I make this clear to the compiler so that it doesn't complain?How/Can I define a case class with members with unbound type parameter like
case class University(p: Person[_])
?