Почему эта циклическая ссылка с проекцией типа недопустима? - PullRequest
14 голосов
/ 16 июля 2011

Следующая псевдоскала выдает ошибку «недопустимая циклическая ссылка»:

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, но япытаясь избежать этого, потому что это может привести к тому, что многие параметры типа будут «заразно» распространяться по всему моему коду.

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

1 Ответ

16 голосов
/ 17 июля 2011

В вашем первоначальном примере вы можете разорвать цикл, введя вспомогательный тип между 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]] ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...