为 "refined" 类型获取正确的类型构造函数参数
Getting proper type constructor parameters for a "refined" type
我在使用反射比较两种类型之间的 'compatibility' 时遇到问题(实际上我正在编写一个宏)。例如,我想允许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()
可以使用名为 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))
然后仍然需要以某种方式找到一种策略来对齐 parents。 (我现在正在测试所有组合)。
我在使用反射比较两种类型之间的 'compatibility' 时遇到问题(实际上我正在编写一个宏)。例如,我想允许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()
可以使用名为 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))
然后仍然需要以某种方式找到一种策略来对齐 parents。 (我现在正在测试所有组合)。