在宏中引入用户命名的变量

时间:2015-05-20 20:10:00

标签: scala macros scala-macros

所以我想定义一个宏,它引入一些变量作为变量声明,这样名称就由宏的用户定义。

说我希望能够写出如下内容。

foldOver(0)(hd, rest)(List(1, 2, 3)) {
  hd + rest
}

我对如何做到这一点的第一个想法是制作变量参数并以某种方式手动检查它们。我满足于以下定义。

def foldOver[A, B](z : B)(next : A, acc : B)(lst : List[A])(f : B): B = macro foldOverImpl[A, B]
def foldOverImpl[A : c.WeakTypeTag, B : c.WeakTypeTag]
                (c: Context)
                (z : c.Expr[B])(next : c.Expr[A], acc : c.Expr[B])
                (lst : c.Expr[List[A]])
                (f : c.Expr[B]): c.Expr[B] = {
    import c.universe._
    (next, acc) match {
      case (TermName(nextName), TermName(accName)) => {
        c.Expr[B](q"""{
          <do whatever here>
        }""")
      }
      case otherwise => {
        throw new Exception("the 'next' and 'acc' variables must be term names")
      }
    }
}

但是当我使用顶部显示的宏时,会给我一个错误,说它无法在程序中找到这些变量名。好吧,它不应该,我希望那些在宏内而不是包含上下文中声明。

那么,有没有办法从用户接收名称并使用它们在宏中声明变量?

1 个答案:

答案 0 :(得分:1)

在def宏中执行此操作是不可能的,因为def宏在扩展之前需要所有参数进行类型检查。宏注释没有此限制,但它们具有可能不适合您的用例的不同语法。