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:
<code>sealed trait Person[+T <: Person[T]] case class Student() extends Person[Student] case class Professor() extends Person[Professor] </code>
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:
<code>case class University(p: Person[_]) </code>
Mas isso falha ao compilar com o erro:
<code>type arguments [Any] do not conform to trait Person's type parameter bounds [+T <: Person[T]] </code>
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):
<code>case class BoundUniversity[P <: Person[P]](p: Person[P]) </code>
Mas esta versão parametrizada não pode ser instanciada com uma variável ilimitada do tipoPerson[_]
:
<code>val p: Person[_] = Student() BoundUniversity(p) </code>
falha ao compilar com:
<code>inferred type arguments [_$1] do not conform to method apply's type parameter bounds [P <: Person[P]] </code>
O mesmo erro acontece para um método com um argumento vinculado como:
<code>def general[P <: Person[P]](p: P) = println(p) </code>
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[_])
?