2011-01-03 9 views
2

私はその特性の型パラメータの型パラメータを型にアクセスしたいと思います。この「二次」型パラメータを別の「一次」パラメータとして型に追加することなく、以下は、この問題を示す:型パラメータの型パラメータへのアクセス

sealed trait A; sealed trait A1 extends A; sealed trait A2 extends A 
trait B[ ASpecific <: A ] { type ASpec = ASpecific } 
trait D[ ASpecific <: A ] extends B[ ASpecific ] 
trait C[ +BSpecific <: B[ _ <: A ]] { 
    def unaryOp : C[ D[ BSpecific#ASpec ]] 
} 

def test(c: C[ B[ A1 ]]) : C[ D[ A1 ]] = c.unaryOp 

試験は明らかに、c.unaryOpそのASPECを示し、タイプC [D []]としないC [D [A1]の結果を持っているので、コンパイルに失敗します_ <:Aのショートカットにすぎず、特定のタイプパラメータを参照していません。

2型パラメータ解決策は単純です:

sealed trait A; sealed trait A1 extends A; sealed trait A2 extends A 
trait B[ ASpecific <: A ] 
trait D[ ASpecific <: A ] extends B[ ASpecific ] 
trait C[ ASpecific <: A, +BSpecific <: B[ ASpecific ]] { 
    def unaryOp : C[ ASpecific, D[ ASpecific ]] 
} 

def test(c: C[ A1, B[ A1 ]]) : C[ A1, D[ A1 ]] = c.unaryOp 

が、私はこの第二、明らかに冗長、パラメータを使用して私のソースを乱雑にする必要がありますなぜ私は理解していません。 B型からそれを検索する方法がないのですか?私はそれがCタイプエイリアスを追加することにより、コンパイル作ることができます

答えて

1

sealed trait A; sealed trait A1 extends A; sealed trait A2 extends A 
trait B[ ASpecific <: A ] { type ASpec = ASpecific } 
trait D[ ASpecific <: A ] extends B[ ASpecific ] 
trait C[ +BSpecific <: B[ _ <: A ]] { 
    type BSpec = BSpecific#ASpec 
    def unaryOp : C[ D[ BSpec ]] 
} 
def test[X <: C[ B[ A1 ]]](c:X): C[ D[ X#BSpec ]] = c.unaryOp 

テストのもう一つの拡張バージョン:

def test2[K <: A, X <: C[ B[ K ]]](c:X): C[ D[ X#BSpec ]] = c.unaryOp 

は、それはあなたの意図を変更していない願っています。

0

@pedrofurla(私がログインせずに尋ねて申し訳ありませんが、直接返信することはできません)

あなたの例では、コンパイルが、私は正確にX#BSpec_ <: Aの別名であるので、あなたがそれから何かが、C[D[A]]を取得されていませんと思います。 ..

val x: C[D[A1]] = test(new C[B[A1]] {}) 

<console>:34: error: type mismatch; 
found : C[D[A]] 
required: C[D[A1]] 
     val x: C[D[A1]] = test(new C[B[A1]] {}) 
          ^
+0

私はより良い外観を持っています... – pedrofurla

+0

これまで成功していません... :( – pedrofurla

関連する問題