为什么带有类型投影的循环引用是非法的?

Kip*_*ros 14 types scala

以下伪Scala产生"非法循环引用"错误:

trait GenT[A]
trait T extends GenT[T#A] {
  type A
}
Run Code Online (Sandbox Code Playgroud)

问题:为什么这是非法的?是否存在稳健性的基本问题,或者它是Scala类型系统的限制?有解决方法吗?

我的目的是创建一个T具有类型成员的特征,该特征A可以通过超级特征按需提升到类型参数GenT[A].例如,一个应用程序可能是约束的表达

def foo[A, S1 <: GenT[A], S2 <: GenT[A]] ...
Run Code Online (Sandbox Code Playgroud)

这可以像使用def foo[S1 <: T, S2 <:T] ...约束那样使用S1#A == S2#A.

如果技术可行,它也可能有助于解决这个问题:如何专注于Scala中的类型投影?

注意:我可以使用GenT而不是在T任何地方,但我试图避免这种情况,因为它会导致许多类型参数在我的所有代码中传播"感染".

下面的两个问题看似相似,但是关于不同类型的循环引用:

Mil*_*bin 16

在您的初始示例中,您可以通过在GenT [A]和T之间引入辅助类型来打破循环,

trait GenT[A]
trait TAux { type A }
trait T extends TAux with GenT[TAux#A]
Run Code Online (Sandbox Code Playgroud)

但是从你激励的例子来看,我认为你不需要走这条路.您所遵循的约束可以使用细化直接表达,

trait T { type A }
def foo[A0, S1 <: T { type A = A0 }, S2 <: T { type A = A0 }] ...
Run Code Online (Sandbox Code Playgroud)

还要记住,您可以通过类型别名将类型成员表示为类型参数,

trait T { type A }
type TParam[A0] = T { type A = A0 }
def foo[A0, S1 <: TParam[A0], S2 <: TParam[A0]] ...
Run Code Online (Sandbox Code Playgroud)