問題を歩き回っていて、型射影と抽象型に関する新しい奇妙な問題を発見しました。トランザクションを生成するシステムがあり、ブリッジしたいピア システムがあるとします。以下は私には良さそうです:
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]
として使用すると問題になることを示唆しています。