Подтвердить что ты не робот

Почему эта циклическая ссылка с незаконченным типом?

Следующий псевдо- Scala дает ошибку "незаконной циклической ссылки":

trait GenT[A]
trait T extends GenT[T#A] {
  type A
}

Вопросы. Почему это незаконно? Есть ли фундаментальная проблема со звуком, или это ограничение системы типа Scala? Есть ли работа?

Мое намерение состоит в создании признака T с членом типа A, который может быть отменен по требованию параметру типа с помощью супер-признака GenT[A]. Одним из приложений может быть выражение ограничений, например

def foo[A, S1 <: GenT[A], S2 <: GenT[A]] ...

Это может быть использовано как def foo[S1 <: T, S2 <:T] ... с ограничением S1#A == S2#A.

Если бы эта техника была возможна, она также могла бы помочь в вопросе: Как специализироваться на проекции типа в Scala?

Примечание. Я мог бы использовать GenT вместо T всюду, но я стараюсь избегать этого, потому что это заставит множество параметров типа распространяться по всему моему "заразительному" коду.

Два приведенных ниже вопроса кажутся похожими, но относятся к различному типу циклической ссылки:

4b9b3361

Ответ 1

В вашем первом примере вы можете разбить цикл, введя вспомогательный тип между GenT [A] и T,

trait GenT[A]
trait TAux { type A }
trait T extends TAux with GenT[TAux#A]

Но из вашего мотивирующего примера я не думаю, что вам нужно идти по этому маршруту. Ограничение, за которым вы после, может быть выражено напрямую с помощью уточнения,

trait T { type A }
def foo[A0, S1 <: T { type A = A0 }, S2 <: T { type A = A0 }] ...

Также имейте в виду, что вы можете нарисовать элемент типа как параметр типа с помощью псевдонима типа,

trait T { type A }
type TParam[A0] = T { type A = A0 }
def foo[A0, S1 <: TParam[A0], S2 <: TParam[A0]] ...