Получение правильных параметров конструктора типа для "уточненного" типа
У меня возникают проблемы при сравнении "совместимости" между двумя типами с помощью отражения (на самом деле я пишу макрос). Например, я хочу разрешить Vector[Int] === List[Int]
, Теперь я знаю общий подход. Но проблема в том, что я не могу получить параметры конструктора типа в этом случае:
import scala.reflect._
import runtime.universe._
typeOf[List[Int]].typeArgs // List(Int) OK
typeOf[List[Int] with java.io.Serializable].typeArgs // List() FAIL
Почему это проблема?
def test[A, B >: A](a: A, b: B)(implicit tt: TypeTag[B]) = {
println(s"tt = $tt")
typeOf[B].typeArgs
}
Теперь это работает:
test(List(1, 2, 3), List(1, 2, 3)) // List(Int)
Но это не так:
test(Vector(1, 2, 3), List(1, 2, 3)) // List()
1 ответ
Решение
Можно использовать экстрактор под названием RefinedType
:
def test[A, B >: A](a: A, b: B)(implicit tt: TypeTag[B]): List[List[Type]] = {
val all = typeOf[B] match {
case RefinedType(parents, scope) => parents.map(_.typeArgs)
case x => x.typeArgs :: Nil
}
all.filter(_.nonEmpty)
}
test(List(1, 2, 3), List(1, 2, 3))
test(Vector(1, 2, 3), List(1, 2, 3))
Тогда еще нужно как-то найти стратегию, чтобы выровнять родителей. (Сейчас проверяю все комбинации).