Accessing type-parameter of a type-parameter
i would like to access, in a trait, the type-parameter of a type-parameter of that trait. without adding this "second-order" type-parameter as another "first-order" parameter to the trait. the following illustrates this problem:
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
the test fails to compile because apparently, the c.unaryOp has a result of type C[D[A]] and not C[D[A1]], indicating that ASpec is merely a shortcut for _ <: A and does not refer to the specific type parameter.
the two-type-parameter solution is simple:
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
but i don't understand why i need to clutter my source with this second, obviously redundant, parameter. is there no way to retrieve it from trait B?
I could make it compile by adding a type alias in C
:
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
Another enhanced version of test:
def test2[K <: A, X <: C[ B[ K ]]](c:X): C[ D[ X#BSpec ]] = c.unaryOp
Hope it haven't changed your intention.
@pedrofurla (sorry can't reply directly as i asked without being logged in)
although your example compiles, i think you are not getting anything from that but C[D[A]]
because precisely X#BSpec
being an alias for _ <: 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]] {})
^
精彩评论