如何大小写匹配包含在泛型类型中的类型变量? [英] How to case match a type variable enclosed in a generic type?
问题描述
我正在编写一个 Scala 子程序来从 2 个类型标签构造一个 TypeTag[Map[_<: A, _<: B]]:
I'm writing a Scala subroutine to construct a TypeTag[Map[_<: A, _<: B]] from 2 typetags:
tag1: TypeTag[Iterable[_<: A]]
tag2: TypeTag[Iterable[_<: B]]
上界是必需的,因为 A 和 B 都被声明为协变的,而 TypeTag[T] 是不变的.
The upperbound is necessary because both A and B are declared as covariant, yet TypeTag[T] is invariant.
我正在尝试使用 case match 来获取 A 和 B 的隐式类型变量,但发现 Scala 中的类型模式匹配相对较弱.即以下代码无法编译:
I'm trying to use case match to get implicit type variables of A and B, but found that type pattern match in Scala is relatively week. Namely, the folloing code fails to be compiled:
(tag1, tag2) match {
case (tt1: TypeTag[Iterable[t1]], tt2: TypeTag[Iterable[t2]]) =>
implicit val t1 = tt1
implicit val t2 = tt2
ScalaReflection.universe.typeTag[Map[t1, t2]]
}
因为无法解析 t1 和 t2.我应该怎么做才能解决这个问题?
because t1 and t2 cannot be resolved. What should I do to fix-circumvent this?
推荐答案
这简化为从 TypeTag[Iterable[t1]]
获取 TypeTag[t1]
.这是可能的,但很丑陋:https://stackoverflow.com/a/25691045/9204.
This reduces to getting a TypeTag[t1]
from a TypeTag[Iterable[t1]]
. Which is possible, but quite ugly: https://stackoverflow.com/a/25691045/9204.
所以你最终会得到类似的东西(未经测试!):
So you end up with something like (untested!):
import scala.reflect.runtime.universe._
def typeToTypeTag[T](
tpe: Type,
mirror: reflect.api.Mirror[reflect.runtime.universe.type]
): TypeTag[T] = {
TypeTag(mirror, new reflect.api.TypeCreator {
def apply[U <: reflect.api.Universe with Singleton](m: reflect.api.Mirror[U]) = {
assert(m eq mirror, s"TypeTag[$tpe] defined in $mirror cannot be migrated to $m.")
tpe.asInstanceOf[U#Type]
}
})
}
def argTypeTag[A](tag: TypeTag[_ /* Actually F[A] for some F */]): TypeTag[A] =
typeToTypeTag[A](tag.tpe.typeArgs.head)
(tag1, tag2) match {
case (tt1: TypeTag[Iterable[t1]], tt2: TypeTag[Iterable[t2]]) =>
implicit val t1 = argTypeTag[t1](tt1)
implicit val t2 = argTypeTag[t2](tt2)
typeTag[Map[t1, t2]]
}
这篇关于如何大小写匹配包含在泛型类型中的类型变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!