Доступ к параметру типа параметра типа - PullRequest
2 голосов
/ 03 января 2011

Я хотел бы получить доступ к признаку типа параметра типа этого признака.без добавления этого параметра типа «второго порядка» в качестве другого параметра «первого порядка» к признаку.следующее иллюстрирует эту проблему:

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

решение с двумя типами параметров простое:

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?

Ответы [ 2 ]

1 голос
/ 04 января 2011

Я могу заставить его скомпилировать, добавив псевдоним типа в 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 голосов
/ 04 января 2011

@ 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]] {})
                             ^
...