以下伪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
,但我试图避免这种情况,因为它会导致许多类型参数在我的所有代码中传播“感染”。
以下两个问题看似相似,但是关于不同类型的循环引用:
答案 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]] ...