Dada una definición de clase con el parámetro de tipo vinculado Animal[A <: String]
parece que el compilador de Scala no infiere B <: String
de Animal[B]
. ¿Está permitida la inferencia? ¿Cómo ayudar al compilador a hacer la inferencia?¿Cómo se definen las clases de casos con miembros con parámetros de tipo no vinculado?
A continuación se muestra un ejemplo concreto con clases de casos donde la falta de esta inferencia es un problema.
Consideremos el siguiente jerarquía de clases caso:
sealed trait Person[+T <: Person[T]]
case class Student() extends Person[Student]
case class Professor() extends Person[Professor]
I necesidad de definir una clase de caso University
que puedo instanciar con una variable de tipo Person[_]
, por ejemplo val p: Person[_] = Student()
. Pensé que esto iba a funcionar con la siguiente definición:
case class University(p: Person[_])
Pero esto no se compila con el error:
type arguments [Any] do not conform to trait Person's type parameter bounds [+T <: Person[T]]
Si Ato el parámetro de tipo de la clase caso University
compila (también compila con parámetros acotados si dejo caer la palabra clave case
pero esto no es una opción en mi caso):
case class BoundUniversity[P <: Person[P]](p: Person[P])
pero esta versión no puede ser parametrizada instanciado con una variable sin límites del tipo Person[_]
:
val p: Person[_] = Student()
BoundUniversity(p)
falla compilar con:
inferred type arguments [_$1] do not conform to method apply's type parameter bounds [P <: Person[P]]
ocurre el mismo error de un método con un argumento atado como:
def general[P <: Person[P]](p: P) = println(p)
por lo que este es no específico para los constructores de clase.
Dos preguntas:
El tipo
Person
se define con límites de parámetrosPerson[+T <: Person[T]]
, de modo que cada instancia de este tipo está asegurado a respetar esos límites:val p: Person[P]
implica queP <: Person[P]
; ¿O me estoy perdiendo algo? Entonces, ¿cómo puedo aclarar esto al compilador para que no se queje?¿Cómo/Puedo definir una clase de caso con miembros con un tipo de parámetro independiente como
case class University(p: Person[_])
?
¿Es necesario que 'T' sea covariante? – leedm777
@dave en mi caso particular 'T' necesita ser covariante, pero creo que esto no cambia el problema: vea el ejemplo introductorio. –
Puede obtener un sitio usando [tipos abstractos] (http://docs.scala-lang.org/tutorials/tour/abstract-types.html), pero luego se vuelven [bastante invariantes] (http: // stackoverflow. com/a/5359015/115478). – leedm777