本文介绍了宏:路径依赖类型推断混淆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我试图简化 AST 的创建,但收到一条奇怪的错误消息:
I tried to simplify the creation of ASTs, but got a weird error message:
case class Box(i: Int)
object M {
import language.experimental.macros
import scala.reflect.makro.Context
case class meth(obj: String, method: String)(implicit val c: Context) {
import c.universe._
def apply(xs: Tree*) =
Apply(Select(Ident(obj), newTermName(method)), xs.toList)
}
def box(n: Int): Box = macro boxImpl
def boxImpl(c: Context)(n: c.Expr[Int]): c.Expr[Box] = {
import c.universe._
implicit val cc: c.type = c
n.tree match {
case arg @ Literal(Constant(_)) =>
meth("Box", "apply").apply(arg)
}
}
}
错误:
<console>:26: error: type mismatch;
found : c.universe.Literal
required: _2.c.universe.Tree where val _2: M.meth
possible cause: missing arguments for method or constructor
meth("Box", "apply").apply(arg)
^
是否可以在 meth
类中推断出正确的类型?或者是否有解决该问题的方法?
Is it possible to infer the correct types into class meth
? Or is there a workaround for the problem?
基于@retronyms 的回答我得到了这个工作:
Based on @retronyms answer I got this to work:
object M {
import language.experimental.macros
import scala.reflect.makro.Context
def meth(implicit c: Context) = new Meth[c.type](c)
class Meth[C <: Context](val c: C) {
import c.universe._
def apply(obj: String, method: String, xs: Tree*) =
Apply(Select(Ident(obj), newTermName(method)), xs.toList)
}
def box(n: Int): Box = macro boxImpl
def boxImpl(c: Context)(n: c.Expr[Int]): c.Expr[Box] = {
import c.universe._
implicit val cc: c.type = c
n.tree match {
case arg @ Literal(Constant(_)) =>
c.Expr(meth.apply("Box", "apply", arg))
}
}
}
推荐答案
当前不允许构造函数具有依赖方法类型 (SI-5712).它在雷达上有待修复,希望是 2.10.1 或 2.11.
Constructors are not currently allowed to have dependent method types (SI-5712). It's on the radar to be fixed, hopefully for 2.10.1 or 2.11.
在此期间,您可以关注 模式 我在 macrocosm 中使用 在宏实现中重用代码.
In the meantime, you can follow the pattern I used in macrocosm to reuse code within macro implementations.
这篇关于宏:路径依赖类型推断混淆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!