// A is a c.WeakTypeTag[A]
// subtype is a Symbol of A's subtype
val sEta = subtype.toType.etaExpand
sEta.finalResultType.substituteTypes(
sEta.baseType(A.tpe.typeSymbol).typeArgs.map(_.typeSymbol),
A.tpe.typeArgs
)
斯卡拉3
// A is a scala.quoted.Type[A]
// subtype is a Symbol of A's subtype
subtype.primaryConstructor.paramSymss match {
// subtype takes type parameters
case typeParamSymbols :: _ if typeParamSymbols.exists(_.isType) =>
// we have to figure how subtypes type params map to parent type params
val appliedTypeByParam: Map[String, TypeRepr] =
subtype.typeRef
.baseType(TypeRepr.of[A].typeSymbol)
.typeArgs
.map(_.typeSymbol.name)
.zip(TypeRepr.of[A].typeArgs)
.toMap
val typeParamReprs: List[TypeRepr] = typeParamSymbols.map(_.name).map(appliedTypeByParam)
subtype.typeRef.appliedTo(typeParamReprs)
// subtype is monomorphic
case _ =>
subtype.typeRef
1条答案
按热度按时间a11xaf1n1#
这是可能的,但类型永远不会应用于您的OOTB。你必须获取类型参数和参数,创建一个带有参数符号和对应参数类型的map/2列表,然后使用
substituteTypes
或类似的技巧。例如,对于子类型,它看起来像这样(我希望超类型是类似的):当然,在像GADT这样的情况下,您最好编写一组测试以确保没有遗漏任何内容,因为使用反射(甚至是编译时),您认为理所当然的许多事情都消失了。