Получение правильных параметров конструктора типа для "уточненного" типа

У меня возникают проблемы при сравнении "совместимости" между двумя типами с помощью отражения (на самом деле я пишу макрос). Например, я хочу разрешить 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))

Тогда еще нужно как-то найти стратегию, чтобы выровнять родителей. (Сейчас проверяю все комбинации).

Другие вопросы по тегам