问题标签 [scala-quasiquotes]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
236 浏览

scala - 具有拟引号的模式匹配树的鲁棒性

我有一个宏,该宏的一部分包括用其他东西替换对某个方法的每个调用。为了做到这一点,我使用 aTransformer并尝试将每个Tree进入transform方法的内容与 quasiquote 进行匹配。当我像下面这样写它时,它似乎工作。

但我认为您应该始终在宏中使用完全限定名称,否则您可能会遇到麻烦。所以我把它写成q"_root_.mypackage.myobject.mymethod[..$_]($value)",但是它不再匹配并且mymethod不再替换调用。
我还查看了 scala 文档中取消引用符号的建议,但我也无法让它发挥作用。

所以我的问题是:这段代码(带有q"mypackage.myobject.mymethod[..$_]($value)")是否总是替换所有调用mymethod而不替换任何其他方法调用?如果没有,我怎样才能使它更健壮?

0 投票
1 回答
315 浏览

scala - Quasiquote 解释树内容而不是作为文字

您能否解释一下为什么下面 Scala quasiquote 的两种用法会在result1和之间给出不同的输出result2?是否可以result3使用 quasiquote 进行复制?即解析字符串内容并评估它?

0 投票
2 回答
1103 浏览

scala - scala - 将值插入准引用

不幸的是,最直观的方式,

结果是

因为$在 quasiquotes 内需要一个tree.

有效,但是非常难看,并且我收到 Intellij 警告,该警告c.literal已弃用,我应该改用 quasiquotes。

所以......我该怎么做?

更新

回应弗拉维安的评论:

0 投票
1 回答
84 浏览

scala - 当我使用宏和 playframework 时编译器崩溃

我写了一个宏来解析JSON成一个匹配的案例类。

以下是它生成的代码(由 last 打印println):

包含宏定义的子项目的编译工作正常。但是当我使用宏编译项目(使用 sbt 0.13.11 和 scala 2.11.8)时,出现以下错误:

0 投票
1 回答
553 浏览

scala - 在插值之前将字符串插入准引号(运行时准引号?)

我正在尝试生成Tree接受案例类值并在给定位置返回案例类参数值的函数。这对于提取私有参数的值很有用。

我还添加了以下依赖项:

positionNone案例类只有一个参数时。

我的解决方案有效,但我怎样才能摆脱tb.parse(s"...")用 quasiquote 替换它 q"..."

我试过了,但它失败了:

据我了解,我不能将一些在运行时构造并q"..."在编译时解析的字符串插入到 quasiquote 中,这与tb.parse. 我对吗?

像这样插值也安全s"(a: $tpe) => $tpe.unapply(a).get$pos"吗?当使用q"..."语法时,quasiquote 知道,$tpeType字符串插值会从中生成一个字符串。我不确定这是否会在更复杂和更具体的情况下始终有效。

0 投票
0 回答
286 浏览

scala - scala 将字符串解析为 Tree 以在准引号中使用

我想知道我是否可以执行一种嵌套的准报价评估。

假设我有一个函数调用

返回"add(x,y)"(一个字符串)

我怎样才能让它评估这个?

就像是

这里的问题是准引号的第一次评估是返回一个字符串,这会导致在第二次评估中不执行任何操作。

0 投票
1 回答
477 浏览

scala - 如何使用 Scala 宏来创建新的部分函数或转换它们?

我在编写转换给定部分函数并创建新部分函数的宏时遇到问题。例如,我希望能够将给定的部分函数分解为其元素——模式绑定器、保护条件和主体;然后我想将模式绑定器和保护条件分解成更小的部分,并从这些部分中重新组装新的部分功能。但是,我在无法调试的宏扩展中遇到奇怪的错误。

给出相同错误的最简单问题是将给定的部分函数分解为 binder、guard 和 body,并将其重新组合成相同的部分函数的代码。

我可以使用简单类型来做到这一点,PartialFunction[Int,Any]但不能使用涉及案例类的类型,PartialFunction[MyCaseClass,Any].

这是有效的代码和无效的代码。

工作代码:获取一个部分函数,​​使用准引号对其进行解构,再次组装相同的函数,然后返回它。

此宏编译并测试通过:

非工作代码:完全相同的宏,除了使用案例类而不是Int作为部分函数的参数。

代码完全相同,只是类型不同(Complicated而不是Simple)。

宏代码编译,但测试编译失败(宏扩展失败):

我已将问题简化为仍然失败的最低限度。在我的实际代码中,类型更复杂,部分函数可能有保护,我确实通过重新排列它的参数和保护来转换部分函数的代码。我有时可以在没有守卫的情况下进行转换,但当偏函数的参数是案例类时则不行。也许守卫的存在并不是问题的根源:当unapply某处存在复合类型时,问题就会发生。我得到的错误消息与上面显示的这个大大简化的示例基本相同。

尽管尝试了许多转换部分函数的替代方法,但我似乎无法解决这个问题:

  • 使用白盒宏上下文
  • 使用普通的准引号,如上例所示
  • 对 case和patterns 使用特殊的 quasiquotes cq"...",如 quasiquotes 的文档中所示pq"..."q"{case ..$cases}"
  • 与警卫匹配:q"{case $binder if $guard => $body }", 也与cqpqquasiquotes
  • 在不同的地方添加c.typecheckor c.untypecheck(这曾经被称为resetAllAttrs,现在已弃用)
  • 不使用准引号,但在原始语法树中执行所有操作:Traverser与原始树匹配一起使用,例如case UnApply(Apply(Select(t@Ident(TermName(_)), TermName("unapply")), List(Ident(TermName("<unapply-selector>")))), List(binder)) if t.tpe <:< typeOf[Blob]等等
  • 尝试将Ident模式匹配器中的Ident' 替换为来自保护条件的 ',反之亦然(这会产生奇怪的错误,“断言失败”,由于类型检查失败)
  • 使用Any而不是特定类型,返回PartialFunction[Any,Any]或总函数Function1[Blob,Any]
  • 使用类型参数T而不是Blob,参数化宏并接受PartialFunction[T,Any]

我将不胜感激任何帮助!我正在使用带有直接宏的 Scala 2.11.8(没有“宏天堂”)。

0 投票
0 回答
218 浏览

scala - 斯卡拉宏。如何实例化子类和动态混合特征

动机:

(与该主题没有紧密关联,但说明了一个用例。可跳过)

Scala.js用来编写React代码。我现在有一个form包含一堆inputs,每个onChange callback在它的道具中都需要一个。请参阅受控组件

问题是:info它与 无关React,但一直与它耦合。我会将控制逻辑与 Web 内容分开。所以我做了:

这只解决了一半的耦合问题。因为TextInputCtrl必须在 React 组件中编写实现才能访问状态。也一样new Input(...),除非TextInputCtrl公开。但是如果你这样做了,你就会在外面携带 React 逻辑。

出色地。如果 trait 可以动态混合到 instance中。Input我可以在其他地方创建一个不受控制的干净实例,并将其传递给 React 组件。灵活得多。这甚至提供了以下杠杆作用:

所以,我做了一些尝试:

问题:

我想使用这个简单的哲学:

但通过宏:

我达到了成功的编译。但在运行时失败:

它抛出:

有什么问题?

这不是问题scala App

==================================================== =

讨论达到脱钩目标的其他方法:

其他方法:(但可能不是最好的解决方案

下面两者都失去了自我类型特征直接访问其他字段的能力。并且难以增量链接或部分覆盖控制逻辑。

或者:

0 投票
0 回答
157 浏览

scala - 在准引用匹配中区分 Tuple1

假设我想要一个宏,它接受一个表达式并在它是一个元组文字时返回它。像这样的东西适用于元组,但返回Some(1)而不是None其他一切:

我知道我可以做这样的事情:

但是感觉应该有更好的方法来区分Tuple1和非元组情况(也许我过去曾使用过它?)。

0 投票
1 回答
260 浏览

scala - 使用 scala meta 和 quasiquotes 定义隐式编码器

我正在尝试使用 Circe 创建一个隐式编码器。然而,这个编码器将使用注释创建,因此我使用的是 Scalameta。这是我的代码。但是,编译器抱怨在 quasiquotes 中有一个覆盖语句。

构建文件如下:

结果我仍然得到: 无法扩展宏注释(最常见的原因是您需要启用宏天堂插件;另一种可能性是您尝试在定义它的同一编译运行中使用宏注释)