问题标签 [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.
scala - 具有拟引号的模式匹配树的鲁棒性
我有一个宏,该宏的一部分包括用其他东西替换对某个方法的每个调用。为了做到这一点,我使用 aTransformer
并尝试将每个Tree
进入transform
方法的内容与 quasiquote 进行匹配。当我像下面这样写它时,它似乎工作。
但我认为您应该始终在宏中使用完全限定名称,否则您可能会遇到麻烦。所以我把它写成q"_root_.mypackage.myobject.mymethod[..$_]($value)"
,但是它不再匹配并且mymethod
不再替换调用。
我还查看了 scala 文档中取消引用符号的建议,但我也无法让它发挥作用。
所以我的问题是:这段代码(带有q"mypackage.myobject.mymethod[..$_]($value)"
)是否总是替换所有调用mymethod
而不替换任何其他方法调用?如果没有,我怎样才能使它更健壮?
scala - Quasiquote 解释树内容而不是作为文字
您能否解释一下为什么下面 Scala quasiquote 的两种用法会在result1
和之间给出不同的输出result2
?是否可以result3
使用 quasiquote 进行复制?即解析字符串内容并评估它?
scala - scala - 将值插入准引用
不幸的是,最直观的方式,
结果是
因为$
在 quasiquotes 内需要一个tree
.
有效,但是非常难看,并且我收到 Intellij 警告,该警告c.literal
已弃用,我应该改用 quasiquotes。
所以......我该怎么做?
更新
回应弗拉维安的评论:
给
scala - 当我使用宏和 playframework 时编译器崩溃
我写了一个宏来解析JSON
成一个匹配的案例类。
以下是它生成的代码(由 last 打印println
):
包含宏定义的子项目的编译工作正常。但是当我使用宏编译项目(使用 sbt 0.13.11 和 scala 2.11.8)时,出现以下错误:
scala - 在插值之前将字符串插入准引号(运行时准引号?)
我正在尝试生成Tree
接受案例类值并在给定位置返回案例类参数值的函数。这对于提取私有参数的值很有用。
我还添加了以下依赖项:
position
当None
案例类只有一个参数时。
我的解决方案有效,但我怎样才能摆脱tb.parse(s"...")
并用 quasiquote 替换它 q"..."
?
我试过了,但它失败了:
据我了解,我不能将一些在运行时构造并q"..."
在编译时解析的字符串插入到 quasiquote 中,这与tb.parse
. 我对吗?
像这样插值也安全s"(a: $tpe) => $tpe.unapply(a).get$pos"
吗?当使用q"..."
语法时,quasiquote 知道,$tpe
但Type
字符串插值会从中生成一个字符串。我不确定这是否会在更复杂和更具体的情况下始终有效。
scala - scala 将字符串解析为 Tree 以在准引号中使用
我想知道我是否可以执行一种嵌套的准报价评估。
假设我有一个函数调用
返回"add(x,y)"
(一个字符串)
我怎样才能让它评估这个?
就像是
这里的问题是准引号的第一次评估是返回一个字符串,这会导致在第二次评估中不执行任何操作。
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 }"
, 也与cq
和pq
quasiquotes - 在不同的地方添加
c.typecheck
orc.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(没有“宏天堂”)。
scala - 斯卡拉宏。如何实例化子类和动态混合特征
动机:
(与该主题没有紧密关联,但说明了一个用例。可跳过)
我Scala.js
用来编写React代码。我现在有一个form
包含一堆input
s,每个onChange callback
在它的道具中都需要一个。请参阅受控组件。
问题是:info
它与 无关React
,但一直与它耦合。我会将控制逻辑与 Web 内容分开。所以我做了:
这只解决了一半的耦合问题。因为TextInputCtrl
必须在 React 组件中编写实现才能访问状态。也一样new Input(...)
,除非TextInputCtrl
公开。但是如果你这样做了,你就会在外面携带 React 逻辑。
出色地。如果 trait 可以动态混合到 instance中。Input
我可以在其他地方创建一个不受控制的干净实例,并将其传递给 React 组件。灵活得多。这甚至提供了以下杠杆作用:
所以,我做了一些尝试:
问题:
我想使用这个简单的哲学:
但通过宏:
我达到了成功的编译。但在运行时失败:
它抛出:
有什么问题?
这不是问题scala App
。
==================================================== =
讨论达到脱钩目标的其他方法:
其他方法:(但可能不是最好的解决方案)
下面两者都失去了自我类型特征直接访问其他字段的能力。并且难以增量链接或部分覆盖控制逻辑。
或者:
scala - 在准引用匹配中区分 Tuple1
假设我想要一个宏,它接受一个表达式并在它是一个元组文字时返回它。像这样的东西适用于元组,但返回Some(1)
而不是None
其他一切:
我知道我可以做这样的事情:
但是感觉应该有更好的方法来区分Tuple1
和非元组情况(也许我过去曾使用过它?)。
scala - 使用 scala meta 和 quasiquotes 定义隐式编码器
我正在尝试使用 Circe 创建一个隐式编码器。然而,这个编码器将使用注释创建,因此我使用的是 Scalameta。这是我的代码。但是,编译器抱怨在 quasiquotes 中有一个覆盖语句。
构建文件如下:
结果我仍然得到: 无法扩展宏注释(最常见的原因是您需要启用宏天堂插件;另一种可能性是您尝试在定义它的同一编译运行中使用宏注释)