scala宏-可用于函数文字



有没有一种方法可以使函数文字的Liftable(使用2.11)?如果我有

case class Validator[T](predicate: T => Boolean)
val predicate = (s: String) => s.startsWith("Hi")

那么我也希望能够准引用predicate

q"new Validator($predicate)"

我希望能神奇地创建一个带有下划线的Liftable。但这有点过于乐观:

implicit def liftPredicate[T: Liftable](f: T => Boolean) = 
  Liftable[T => Boolean]{ f => q"$f(_)" }

看了StandardLiftables,我想不出如何解决这个问题。

从另一个角度来看:

假设我想在编译时用宏从以下类创建实例:

abstract class ClassWithValidation {
  val predicate: String => Boolean
  def validate(s: String) = predicate(s)
}

我从其他地方检索一个函数文字作为变量值:

val predicate = (s: String) => s.startsWith("Hi")

然后我想简单地在结构中引用这个变量:

q"""new ClassWithValidation {
      val predicate = $predicate
      // other stuff...
    }"""

但它给了我一个错误:

Error:(46, 28) Can't unquote String => Boolean, consider providing an 
implicit instance of Liftable[String => Boolean]

通常,我可以为自定义类型创建这样的隐式Liftable。但我还没有找到一种方法来做同样的功能文字。有没有办法做到这一点,或者我需要换一种方式来看待它?

据我所知,您正试图从一个函数转到一个表示其源代码的抽象语法树(以便将其拼接到宏扩展中)。这是人们经常要求的事情(例如,它经常出现在DSL中),但在我们当前的宏观系统中,没有直接的方法来实现这一点。

目前,您可以做的是在声明函数时显式保存AST,然后在宏中加载并使用它。最方便的方法是通过另一个宏:https://gist.github.com/xeno-by/4542402.人们还可以想象写一个宏注释,它将按照相同的思路工作。

在Project Palladium中,有一个为正在编译的每个程序保存类型检查树的计划。这意味着很可能会有一个简单的API,例如treeOf(predicate),它将自动返回包含谓词源的抽象语法树。但这绝对不是板上钉钉的事情——我们会看看进展如何,我会在今年的ScalaDays上汇报进展。

相关内容

  • 没有找到相关文章

最新更新