Jak zdefiniować klasy przypadków z elementami o niezwiązanych parametrach typu?
Dana definicja klasy z parametrem typu powiązanegoAnimal[A <: String]
wydaje się, że kompilator Scala nie wnioskujeB <: String
zAnimal[B]
. Czy wnioskowanie jest dozwolone? Jak pomóc kompilatorowi w wyciągnięciu wniosku?
Poniżej znajduje się konkretny przykład z klasami przypadków, w których brak tego wnioskowania stanowi problem.
Rozważ następującą hierarchię klas przypadków:
<code>sealed trait Person[+T <: Person[T]] case class Student() extends Person[Student] case class Professor() extends Person[Professor] </code>
Muszę zdefiniować klasę sprawyUniversity
które mogę utworzyć za pomocą zmiennej typuPerson[_]
, na przykładval p: Person[_] = Student()
. Myślałem, że to zadziała z następującą definicją:
<code>case class University(p: Person[_]) </code>
Ale nie udaje się skompilować z błędem:
<code>type arguments [Any] do not conform to trait Person's type parameter bounds [+T <: Person[T]] </code>
Jeśli wiążę parametr typu klasy caseUniversity
kompiluje (kompiluje również z nieograniczonymi parametrami, jeśli upuszczęcase
słowo kluczowe, ale w moim przypadku nie jest to opcja):
<code>case class BoundUniversity[P <: Person[P]](p: Person[P]) </code>
Ale tej sparametryzowanej wersji nie można utworzyć instancją z nieograniczoną zmienną typuPerson[_]
:
<code>val p: Person[_] = Student() BoundUniversity(p) </code>
nie udaje się skompilować z:
<code>inferred type arguments [_$1] do not conform to method apply's type parameter bounds [P <: Person[P]] </code>
Ten sam błąd występuje w przypadku metody z powiązanym argumentem, takiej jak:
<code>def general[P <: Person[P]](p: P) = println(p) </code>
więc nie jest to specyficzne dla konstruktorów klas.
Dwa pytania:
TypPerson
jest definiowany z ograniczeniami parametrówPerson[+T <: Person[T]]
, tak aby każda instancja tego typu była ubezpieczona w celu przestrzegania tych granic:val p: Person[P]
oznacza toP <: Person[P]
; czy coś mi brakuje? Jak więc mogę to wyjaśnić kompilatorowi, aby nie narzekał?
Jak / mogę zdefiniować klasę przypadków z elementami o parametrze typu niezwiązanego, takimi jakcase class University(p: Person[_])
?