gpt4 book ai didi

scala - 在 Scala 中将函数文字与 quasiquotes 匹配

转载 作者:行者123 更新时间:2023-12-03 10:17:18 24 4
gpt4 key购买 nike

这个问题的动机与我的 previous question 相似(尽管这是关于我在 different context 中遇到的问题)。

我可以很容易地对函数文字进行模式匹配,而无需 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()

现在假设我想使用 quasiquotes 更灵活地进行相同类型的匹配。以下内容也将匹配该功能,并打印出我们期望的内容。
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 匹配函数文字时指定参数的类型,或者匹配未知数量的参数?

最佳答案

使用 2.10 和 vanilla 2.11 的最新天堂插件,您可以这样做:

val q"(..$args) => $body" = f.tree

我刚刚用 paradise example project 测试过了与以下 Macros.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"()")
}
}

Test.scala :
object Test extends App {
Macro((x: Int) => x + 1)
}

您可以在 corresponding chapter of quasiquote guide 中阅读有关使用准引号处理函数树的更多信息。 .

关于scala - 在 Scala 中将函数文字与 quasiquotes 匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18560023/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com