Scala中函数文字与拟文字的匹配

Scala中函数文字与拟文字的匹配,scala,macros,scala-macros,scala-quasiquotes,Scala,Macros,Scala Macros,Scala Quasiquotes,这个问题在动机上与我的类似(尽管它是关于我在一次面试中遇到的一个问题) 我可以很容易地在函数文本上进行模式匹配,而无需使用quasiquotes: import scala.reflect.macros.Context import scala.language.experimental.macros object QQExample { def funcDemo(f: Int => String) = macro funcDemo_impl def funcDemo_impl(

这个问题在动机上与我的类似(尽管它是关于我在一次面试中遇到的一个问题)

我可以很容易地在函数文本上进行模式匹配,而无需使用quasiquotes:

import scala.reflect.macros.Context
import scala.language.experimental.macros

object QQExample {
  def funcDemo(f: Int => String) = macro funcDemo_impl
  def funcDemo_impl(c: Context)(f: c.Expr[Int => String]) = {
    import c.universe._

    f.tree match {
      case Function(ps, body) => List(ps, body) foreach println
      case _ => c.abort(
        c.enclosingPosition,
        "Must provide a function literal."
      )
    }

    c.literalUnit
  }
}
其工作原理如下:

scala> QQExample.funcDemo((a: Int) => a.toString)
List(val a: Int = _)
a.toString()
现在假设我想使用Quasikotes更灵活地进行相同类型的匹配。以下内容也将与该函数匹配,并打印我们期望的内容

case q"($x: $t) => $body" => List(x, t, body) foreach println
但是如果我想在模式中指定类型,它不匹配:

case q"($x: Int) => $body" => List(x, body) foreach println
甚至没有以下任何一项:

case q"$p => $body"      => List(p,  body) foreach println
case q"($p) => $body"    => List(p,  body) foreach println
case q"..$ps => $body"   => List(ps, body) foreach println
case q"(..$ps) => $body" => List(ps, body) foreach println

在将函数文字与quasiquotes匹配时,是否可以指定参数的类型,或者匹配未知数量的参数?

对于最新的paradise插件2.10和vanilla 2.11,您可以这样做:

val q"(..$args) => $body" = f.tree
我刚刚用以下
宏对其进行了测试。scala

import language.experimental.macros
import scala.reflect.macros.Context

object Macro {
  def apply(f: Any): Any = macro impl
  def impl(c: Context)(f: c.Expr[Any]) = { import c.universe._
    val q"(..$args) => $body" = f.tree
    println(s"args = $args, body = $body")
    c.Expr(q"()")
  }
}
object Test extends App {
  Macro((x: Int) => x + 1)
}
Test.scala

import language.experimental.macros
import scala.reflect.macros.Context

object Macro {
  def apply(f: Any): Any = macro impl
  def impl(c: Context)(f: c.Expr[Any]) = { import c.universe._
    val q"(..$args) => $body" = f.tree
    println(s"args = $args, body = $body")
    c.Expr(q"()")
  }
}
object Test extends App {
  Macro((x: Int) => x + 1)
}

在中,您可以阅读更多关于使用quasiquotes处理函数树的信息

那是一只虫子。上一个代码块中的所有模式都应该适用于单参数匿名函数。当修复程序合并到中时,请按照以下步骤获得通知master@DenShabalin:谢谢!修复程序位于2.11拉取请求队列中。合并后,我将把它向后移植到2.10。我说所有的模式都会起作用也有点错误。您必须在参数上使用括号(即模式2和模式4)@DenShabalin匹配函数类型是否也有效?我成功地匹配了如下
val q“Capture.Capture[$tp]=tree
,树为
Capture[()=>R]
Capture[A=>R]
Capture[(A,B)=>R]
,等等。接下来我无法匹配
val tq”(..$ts)=>$tr tp。请给我一个应该怎么做的提示。@DenShabalin:这不是一个答案吗?