【问题标题】:How to match on a tree of arrow association (`x->y`) in Scala macros?如何在 Scala 宏中匹配箭头关联树(`x->y`)?
【发布时间】:2014-07-09 18:47:54
【问题描述】:

我想对 Scala 宏中的 x -> y 操作树进行模式匹配。我正在针对 Scala 2.10.4(使用 Macro Paradise)和 Scala 2.11.x 进行交叉编译。我尝试了以下模式,但都没有奏效:

arrowTree match {
  case q"$x -> $y"                                            => ???
  case q"scala.Predef.ArrowAssoc[${_}, ${_}]($x).->$y"        => ???
  case q"_root_.scala.Predef.ArrowAssoc[${_}, ${_}]($x).->$y" => ???
  case q"_root_.scala.Predef.ArrowAssoc($x).->$y"             => ???
}

什么模式可以让这个匹配同时适用于 2.10.4 和 2.11.x?

【问题讨论】:

  • 什么是q?我只见过sfraw 用于字符串插值...那么q 是什么?
  • 准引号,用于从字符串创建树
  • q"$x -> $y" 怎么样?您没有在准引号中分配任何变量,它们是不正确的。
  • 谢谢我在x和y前面加了$。

标签: scala macros scala-quasiquotes


【解决方案1】:

在一个完美的世界里,你肯定会期望第一个匹配,但这并不是那么简单。

每当您在 Scala 中编写 foo -> bar 时,您实际上是在调用像 foo.->(bar) 这样的方法。当 typechecker 试图找到一个名为 -> 的方法时,它会失败并开始寻找任何可能将该方法添加到 foo 的隐式,它通常会找到一个 Predef.ArrowAssoc,它将原始表达式转换为 scala.this.Predef.ArrowAssoc[Int](1).->[Int](2)

为了匹配这个,你可以使用以下模式:

case q"scala.this.Predef.ArrowAssoc[$_]($foo).->[$_]($bar)" =>

这里我们将通配符放在类型参数的位置,因为我们暂时不关心这些。

在 2.10 上,模式会略有不同,因为那时隐式的命名方式不同:

case q"scala.this.Predef.any2ArrowAssoc[${_}]($foo).->[${_}]($bar)" =>

这里的另一个区别是需要在通配符周围使用花括号。 2.10 不支持字符串插值器中的 $_ 语法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-19
    • 2014-10-30
    • 2012-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多