我正在解决一个问题,我发现类型投影和抽象类型有一个新的奇怪问题。假设我有一个产生交易的系统,并且有一个我想桥接的对等系统。以下对我来说看起来不错:
trait Txn[S <: Sys[S]] {
def peer: S#Peer#Tx
def newID(): S#ID
def newVar[A](id: S#ID, init: A): S#Var[A]
}
trait Sys[S <: Sys[S]] {
type Tx <: Txn[S]
type Peer <: Sys[Peer] // parallel system
type Var[A]
type ID
}
我可以使用直接系统:
def directWorks[S <: Sys[S]](implicit tx: S#Tx): Unit = {
val id = tx.newID()
val v = tx.newVar(id, 0)
}
但不知何故,peer
交易的方法存在缺陷,如下所示:
def indirectDoesnt[S <: Sys[S]](implicit tx: S#Tx): Unit = {
val p = tx.peer
val id = p.newID()
val v = p.newVar(id, 0) // what the **** - id is not compatible??
}
error: type mismatch;
found : id.type (with underlying type S#Peer#ID)
required: _30129.Peer#ID where val _30129: S
val v = p.newVar(id, 0)
^
我想变得聪明并解决它:
def clever[S <: Sys[S]](implicit tx: S#Tx): Unit = {
def directWorks[S <: Sys[S]](implicit tx: S#Tx): Unit = {
val id = tx.newID()
val v = tx.newVar(id, 0)
}
directWorks(tx.peer)
}
...但这也失败了,提供了更多关于问题所在的线索:
error: inferred type arguments [S#Peer] do not conform to method
directWorks's type parameter bounds [S <: Sys[S]]
directWorks(tx.peer)
^
这一切都表明,要么def peer: S#Peer#Tx
引入一个问题,要么(更有可能?)type Peer <: Sys[Peer]
当不用作类型参数但类型成员时有问题。