2011-01-03 2 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 результат типа C [D [А]], а не C [D [A1]], что указывает на ASpec является просто ярлыком для _ <: A и не относится к определенному параметру типа.

два типа-параметра Решение простое:

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?

ответ

1

я мог бы сделать его компиляцию, добавив псевдоним типа в 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 

Другой расширенную версию теста:

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

Надеется, что это не изменило свое намерение.

0

@pedrofurla (извините, не могу ответить прямо, как я спросил без входа)

хотя ваш пример компилирует, я думаю, что вы от этого ничего, кроме C[D[A]] не получают, потому что именно X#BSpec быть псевдоним для _ <: 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

Смежные вопросы