2016-04-23 4 views
2

У меня возникают проблемы с сопоставлением «совместимости» между двумя типами с использованием отражения (на самом деле я пишу макрос). Например, я хочу разрешить Vector[Int] === List[Int]. Теперь я знаю general approach. Но проблема в том, что я не могу получить параметры типа конструктора в этом случае:Получение правильных параметров конструктора типа для «уточненного» типа

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() 

ответ

0

можно использовать экстрактор под названием 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)) 

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

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