10

我是 scala 宏的新手,我花了几天时间尝试编写我的第一个宏。我对 quasiquotes 连接有疑问。

有一个 case 子句列表,假设如下:

val cases = cq"x => 1 " :: cq"_ => 0 " :: Nil

我需要从中构建一个部分函数。问题是我不知道如何将它们粘贴到最终的准引用中。文档说我应该这样做:

q"{ case ..$cases }"

但如果我这样做是行不通的。

有没有办法从这样的列表中构建 PartialFunction ?

谢谢你的帮助。

4

1 回答 1

5

以下适用于 2.11.2:

import scala.reflect.macros.Context
object Macros {
    def partial: PartialFunction[Int, Int] = macro partialImpl
    def partialImpl(c: Context): c.Expr[PartialFunction[Int, Int]]= {
        import c.universe._
        val cases = cq"x => 1 " :: cq"_ => 0 " :: Nil
        val pf = q"{ case ..$cases } : PartialFunction[Int, Int]"
        c.Expr[PartialFunction[Int, Int]](pf)

    }
}

然后您可以调用Macros.partial(1),例如,或Macros.partial.isDefinedAt(2)

请注意,为了完成这项工作,我必须PartialFunction[Int, Int]在 quasiquote中明确使用q"{ case ..$cases } : PartialFunction[Int, Int]"。如果没有明确的类型定义(否则假设PartialFunction[Any, Int]),它就无法工作。

是偏函数的 quasiquote 语法规范。它作为纯语法树工作,但显然不能被解释为类型化表达式PartialFunction[Any, T],除非类型被明确表示,否则只能通过宏来解释。

于 2015-05-20T13:49:26.047 回答