Como definir classes de casos com membros com parâmetros de tipo não acoplados?
Dada uma definição de classe com parâmetro de tipo vinculadoAnimal[A <: String]
parece que o compilador Scala não infereB <: String
deAnimal[B]
. A inferência é permitida? Como ajudar o compilador a fazer a inferência?
Abaixo está um exemplo concreto com classes de casos em que a falta dessa inferência é um problema.
Considere a seguinte hierarquia de classes de casos:
sealed trait Person[+T <: Person[T]]
case class Student() extends Person[Student]
case class Professor() extends Person[Professor]
Eu preciso definir uma classe de casoUniversity
que eu posso instanciar com uma variável do tipoPerson[_]
, por exemploval p: Person[_] = Student()
. Eu pensei que isso funcionaria com a seguinte definição:
case class University(p: Person[_])
Mas isso falha ao compilar com o erro:
type arguments [Any] do not conform to trait Person's type parameter bounds [+T <: Person[T]]
Se eu ligar o parâmetro type da classe caseUniversity
compila (também compila com parâmetros ilimitados se eu derrubar ocase
palavra-chave, mas isso não é uma opção no meu caso):
case class BoundUniversity[P <: Person[P]](p: Person[P])
Mas esta versão parametrizada não pode ser instanciada com uma variável ilimitada do tipoPerson[_]
:
val p: Person[_] = Student()
BoundUniversity(p)
falha ao compilar com:
inferred type arguments [_$1] do not conform to method apply's type parameter bounds [P <: Person[P]]
O mesmo erro acontece para um método com um argumento vinculado como:
def general[P <: Person[P]](p: P) = println(p)
então isso não é específico para os construtores de classe.
Duas questões:
O tipoPerson
é definido com limites de parâmetrosPerson[+T <: Person[T]]
, para que cada instância desse tipo seja segurada para respeitar esses limites:val p: Person[P]
implica queP <: Person[P]
; Ou eu estou esquecendo de alguma coisa? Então, como posso deixar isso claro para o compilador para que ele não reclame?
Como / Posso definir uma classe de caso com membros com parâmetro de tipo não vinculado comocase class University(p: Person[_])
?