Учитывая определение класса с параметром связанного типа Animal[A <: String]
кажется, что компилятор Scala не выводит B <: String
из Animal[B]
. Разрешен ли вывод? Как помочь компилятору сделать вывод?
Ниже приведен конкретный пример с прецедентными классами, где отсутствие такого вывода является проблемой.
Рассмотрим следующую иерархию классов case:
sealed trait Person[+T <: Person[T]]
case class Student() extends Person[Student]
case class Professor() extends Person[Professor]
Мне нужно определить класс case University
, который я могу создать с помощью переменной типа Person[_]
, например val p: Person[_] = Student()
. Я думал, что это будет работать со следующим определением:
case class University(p: Person[_])
Но это не компилируется с ошибкой:
type arguments [Any] do not conform to trait Person's type parameter bounds [+T <: Person[T]]
Если я привязываю параметр типа кейс-класса Университет
, он компилируется (он также компилируется с неограниченными параметрами если я уберу ключевое слово case
, но это не вариант в моем случае):
case class BoundUniversity[P <: Person[P]](p: Person[P])
Но эта параметризованная версия не может быть создана с неограниченной переменной типа Person[_]
:
val p: Person[_] = Student()
BoundUniversity(p)
Ошибка компиляции с:
inferred type arguments [_$1] do not conform to method apply's type parameter bounds [P <: Person[P]]
Та же ошибка возникает для метода с привязанным аргументом, например:
def general[P <: Person[P]](p: P) = println(p)
так что это не относится к конструкторам классов.
Два вопроса:
Тип Person
определен с границами параметров Person[+T <: Person[T]]
, так что каждый экземпляр этого типа застрахован для соблюдения этих границ: val p: Person[P]
подразумевает, что P <: Person[P]
; или я что-то упускаю? Итак, как я могу сделать это понятным для компилятора, чтобы он не жаловался?
Как/можно ли определить класс case с членами с параметром несвязанного типа, например case class University(p: Person[_])
?