Почему этот код Scala не проходит проверку типов?
trait T { type A }
trait GenFoo[A0, S <: T { type A = A0 }]
trait Foo[S <: T] extends GenFoo[S#A, S]
Я не понимаю, почему «аргументы типа [S#A,S] не соответствуют границам параметра типа типажей GenFoo [A0,S ‹: T{type A = A0}]». Есть ли обходной путь?
Изменить. Как уже отмечалось, ошибка соответствия связана с невозможностью проверки S <: T{type A = S#A}
. Даниэль Собрал указал на -explaintypes
, что говорит нам:
S <: T{type A = S#A}?
S <: T?
true
S specializes type A?
this.A = this.A?
S = this.type?
false
false
false
false
Я не уверен, как это интерпретировать.
Обратите внимание, что мы получим недопустимую циклическую ссылку, если попытаемся определить
trait Foo[S <: T { type A = S#A } ] extends GenFoo[S#A, S]
хотя уточнение типа здесь, кажется, не добавляет никакой новой информации. (См. также Почему эта циклическая ссылка с проекцией типа незаконно?)
Моя мотивация — создать трейт Foo[S <: T]
, который специализируется на S#A
, например: Как специализироваться на проекции типов в Scala? Чтобы заставить это работать, я пытаюсь представить S#A
как явный параметр A0
в свойстве реализации GenFoo
, который можно специализировать напрямую. Я надеялся применить идею уточнения типа из ответа Майлза Сабина на Почему эта циклическая ссылка с проекцией типа недопустима? но я сталкиваюсь с этой ошибкой соответствия.