2016-04-23 19 views
2

Ich habe Probleme beim Vergleich der "Kompatibilität" zwischen zwei Typen mit Reflektion (tatsächlich schreibe ich ein Makro). Zum Beispiel möchte ich Vector[Int] === List[Int] erlauben. Jetzt kenne ich die general approach. Aber das Problem ist, ich kann die Typkonstruktor Parameter in diesem Fall nicht erhalten:Erhalte die richtigen Typenkonstruktorparameter für einen "verfeinerten" Typ

Warum ist das ein Problem?

def test[A, B >: A](a: A, b: B)(implicit tt: TypeTag[B]) = { 
    println(s"tt = $tt") 
    typeOf[B].typeArgs 
} 

Jetzt funktioniert das:

test(List(1, 2, 3), List(1, 2, 3)) // List(Int) 

Aber dies nicht:

test(Vector(1, 2, 3), List(1, 2, 3)) // List() 

Antwort

0

Man kann einen Extraktor RefinedType genannt verwenden:

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

Dann noch hat man irgendwie fin d eine Strategie, um die Eltern auszurichten. (Ich teste jetzt alle Kombinationen).