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

时间:2011-07-16 19:50:22

标签: scala types

以下伪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

如果技术可行,它也可能有助于解决问题:How to specialize on a type projection in Scala?

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

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

1 个答案:

答案 0 :(得分:16)

在您的初始示例中,您可以通过在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]] ...