在宏中传递和调用高阶函数

时间:2013-08-31 06:20:33

标签: scala scala-macros

Compilation issue when accessing parameter value in Scala macro开始,我想定义一个应用谓词的宏。如果语句fn = c.eval(pred)存在,则客户端代码无法编译,没有任何关于问题性质的指示。

def fnInvocation( value : Int, pred : c.Expr[ Int => Boolean ] ): Boolean = fnInvocationImpl

def fnInvocationImpl(c: Context)( value : Int, pred : c.Expr[ Int => Boolean ] ) : c.Expr[Boolean] = {
    var fn = x => x % 2 == 0
    //    fn = c.eval( pred ) // client compilation fails if this line is included
    val result = fn( value )
    c.literal( result )
}

我是否可以在宏中执行此操作?

1 个答案:

答案 0 :(得分:1)

宏方法本身没有初始上下文参数列表,并且它们具有表达式参数没有意义。另一方面,在它们的实现中,每个参数(在具有上下文的初始参数列表之后)必须是表达式。

在您的情况下,签名需要如下所示:

def fnInvocation(value: Int, pred: Int => Boolean): Boolean =
  macro fnInvocationImpl

def fnInvocationImpl(c: Context)(
  value: c.Expr[Int],
  pred: c.Expr[Int => Boolean]
): c.Expr[Boolean] = ???

my previous answer中的评论也适用于此处。如果两个参数都是编译时文字,则可以在编译时执行应用程序 - 请参阅my gist here for an example这种事情如何与函数文字一起使用。如果它们不是两个文字,您可以构建一个在运行时执行应用程序的树。您甚至可以检查参数是否都是文字,应用函数并返回编译时文字,如果是,则返回生成树。你不能做的是在编译时执行应用程序,如果值不是文字。