使用Scala宏将类型构造函数应用于生成的类型参数

使用Scala宏将类型构造函数应用于生成的类型参数,scala,reflection,macros,type-constructor,materialize,Scala,Reflection,Macros,Type Constructor,Materialize,我正试图具体化(简化)特征的一个实例 使用Scala宏。因此,宏的签名是 def materialize[F[_]](c: Context)( implicit fT: c.WeakTypeTag[F[_]]): c.Expr[TC[F]] 类型构造函数F[\u]现在需要应用于类型参数A,原因有两个: 要为特定的F(如Foo[a])写入上面的签名,请应用) 检查类型Foo[A]的成员,以指定apply的有趣主体 是否有任何方法可以创建与方法类型参数A相对应的类型,该类型可以在applied

我正试图具体化(简化)特征的一个实例

使用Scala宏。因此,宏的签名是

def materialize[F[_]](c: Context)(
  implicit fT: c.WeakTypeTag[F[_]]): c.Expr[TC[F]]
类型构造函数
F[\u]
现在需要应用于类型参数
A
,原因有两个:

  • 要为特定的
    F
    (如
    Foo[a]
    )写入上面的
    签名,请应用
  • 检查类型
    Foo[A]
    的成员,以指定
    apply的有趣主体
  • 是否有任何方法可以创建与方法类型参数
    A
    相对应的类型,该类型可以在
    appliedType
    中使用?这对我来说似乎很困难,因为方法
    apply
    及其类型参数
    A
    也只是作为树生成的


    我试图将
    WeakTypeTag[TC[F]]
    作为宏调用的附加参数,并通过

    val paramT = wfg.tpe.member("apply": TermName).tpe.typeParams.head.tpe
    
    但是在
    q中使用
    paramT
    “…def apply[$paramT]…”
    确实会导致

    java.lang.IllegalArgumentException: can't splice "A" as type parameter
    

    因此,这似乎也不是解决方案。

    我通过将上述特征的定义更改为

    trait TC[F[_]] {
      type ApplyF[A] = F[A]
      def apply[A](fa: ApplyF[A]): ApplyF[A]
    }
    
    键入检查树中的伪值

    typecheck(q"""new TC[Foo] {
      def apply[A](fa: ApplyF[A]): ApplyF[A] = ???
    }""").tpe
    
    然后,可以(通过)销毁和转换类型检查结果,以填充
    。这并没有完全解决问题,导致类型错误:

    found   : A(in method apply)(in method apply)(in method apply)...
    required: A(in method apply)(in method apply)(in method apply)...
    
    在返回树之前调用
    untypecheck
    没有帮助-但是对结果树的检查表明预期结果是有效的(类型正确的)Scala代码。因此,使宏最终运行的最后一步是调用

    parse(showCode(result))
    

    感觉完全没有必要,但似乎这是摆脱冲突类型信息的唯一方法。

    您使用的是scala 2.10吗?另外,说到
    java.lang.IllegalArgumentException:不能将“A”拼接为类型参数
    ,您可以共享完整的代码吗?嘿,Eugene,我一直在使用2.10,但就我所注意到的,在2.10和2.11.2之间切换并没有任何区别。完整(最终工作)代码现在您是否尝试过
    appliedType
    parse(showCode(result))