如果我有以下
Scala类型层次结构:
// Base traits trait TA[X <: TA[X,Y],Y <: TB[X,Y]] trait TB[X <: TA[X,Y]] trait TC[X <: TA[X,_]] // More specific traits trait TI[X <: TI[X,Y <: TJ[X,Y]] extends TA[X,Y] trait TJ[X <: TI[X,Y]] extends TB[X,Y] trait TK[X <: TI[X,_]] extends TC[X] // Concrete class that should implement TK,but does not compile class Z extends TK[TI[_,_]] // What is needed to be able to get class Z to compile // The reference of X to itself has been removed. trait TC2[X <: TA[_,_]] trait TK2[X <: TI[_,_]] extends TC2[X] class Z2 extends TK2[TI[_,_]]
TC将是某种TA的通用经理.
TK将是更具体的TA(TI)的更具体的管理者.
Z将是管理实现TI的任何对象的具体实现.
Z不合法,但Z2是.不幸的是,TC和TK比TC2和TK2更具特异性.那么有没有办法用TC和TK来代替TC,而不是TC2和TK2?
[编辑]我没有在我原来的问题中说,我有点理解为什么Z不健全.我真正想知道的是,如果有一种方式可以说:
class Z3 extends TK[TI[TI,_]]
解决方法
当您具有复杂的相互递归类型边界时,通常可以帮助您查看是否可以使用抽象类型成员将问题转换为等效的问题.如果我们机械地做到这一点,你的基础和更具体的特征最终看起来像,
// Base traits trait TA { type X <: TA type Y <: TB } trait TB { type X <: TA type Y <: TB } trait TC { self => type X <: TA { type X <: self.X } } // More specific traits trait TI extends TA { type X <: TI type Y <: TJ } trait TJ extends TB { type X <: TI type Y <: TJ } trait TK { self => type X <: TI { type X <: self.X } }
现在我们有一个简单的Z定义,
class Z extends TK { type X = TI }
注意,TA,TB和TI,TJ的成员的定义基本相同.因为这些类型现在是类型成员,所以我们可以将它们分解为常见的基类型,如下所示,
// Base traits trait T0 { type X <: TA type Y <: TB } trait TA extends T0 trait TB extends T0 trait TC { self => type X <: TA { type X <: self.X } } // More specific traits trait T1 extends T0 { type X <: TI type Y <: TJ } trait TI extends TA with T1 trait TJ extends TB with T1 trait TK extends TC { self => type X <: TI { type X <: self.X } } class Z extends TK { type X = TI }