简而言之:以下内容无法编译(原因如下),我怎样才能使其工作?
trait Simulator {
type CM[T]
def useCM(v: CM[_])
}
case class CMH[S <: Simulator,T](cm: S#CM[T])
class SimIterator[S <: Simulator](val sim: S, val cmhs: Seq[CMH[S,_]]) {
cmhs foreach { cmh => sim.useCM(cmh.cm) }
/*
compile time error:
type mismatch; found : cmh.cm.type (with underlying type S#CM[_$2]) required:
SimIterator.this.sim.CM[_] Note: _$2 <: Any (and cmh.cm.type <: S#CM[_$2]),
but type CM is invariant in type T. You may wish to define T as +T instead.
(SLS 4.5)
*/
}
该结构背后的想法是CMH
hides T
-具体行为来自SimIterator
后者处理常见任务。S
用于强制值CMH
拥有正确的类型而无需实例Simulator
.
In the foreach
,似乎存在与以下相关的子类型问题CM
. If S#CM
是我们需要的具体类型sim.CM =:= S#CM
。但是,请看以下内容:
object Test extends Simulator {
type CM[T] = Option[T]
def useCM(v: CM[_]) = println(v)
def mkCM[T]: CM[T] = None
CMH[Simulator,AnyRef](mkCM[AnyRef])
}
我们现在有一个CMH
我们可以传递到SimIterator
与任何一起Simulator
。所以显然打字SimIterator
限制不够。如何表达(和使用)S =:= sim.type
?
UPDATE
这可以工作,但不能在构造函数中使用(非法依赖方法类型:参数出现在同一部分或较早部分中另一个参数的类型中)
class SimIterator(val sim: Simulator) {
def doIt(cmhs: Seq[CMH[sim.type,_]]) {
cmhs foreach { cmh => sim.useCM(cmh.cm) }
}
}
上面的例子可以工作,但是not我想要的是。cmhs
应在构造时传入。