问题标签 [scala-2.13]

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 回答
207 浏览

scala - 在 scala 宏中,如何从 WeakTypeTag 中检索完整的类型信息?

我正在编写宏来将类型描述转换为单例类型:

问题是因为 A 只有一个 WeakTypeTag。它无法从泛型类型中提取正确的信息:

这给出了错误的见证类型:shapeless.Witness.Aux[String("T1 ^^ T2")]

所以我的问题是:

  1. 是编译时,类型信息应该是完全可见的,为什么 T1 和 T2 被擦除了?

  2. 如何修复此程序,使其提供正确的类型信息:

shapeless.Witness.Aux[String("Int ^^ String")]

?

0 投票
2 回答
59 浏览

scala - 在 scala 宏中,如何在编译时提升一个对象并在 quasiquote 中使用它?

下面的代码片段是一个来自 thinkworks 项目的简短 scala 宏包定义:

(由https://github.com/ThoughtWorksInc/feature.scala/blob/4d19cc19016d85f26925895f43f618e1b7552d09/SelfType/src/main/scala/com/thoughtworks/feature/SelfType.scala提供)

最后一行作为 quasiquote 似乎包含很多样板文本:

假设这个宏包被定义在一个特征中作为家族多态性设计模式的一部分:没有确定性q"_root_.com.thoughtworks.feature.SelfType.make[$a, $out]",它必须vvv在编译时从宏包的对象变量派生。如何使用此变量使准引用更短且更具适应性?

可能有多种方法可以实现这一点(例如,对于每个实现,为SelfType对象定义一个 Liftable)。但这更是样板。我正在寻找最短的解决方案。理想情况下,是这样的:

0 投票
1 回答
56 浏览

scala - 在scala中,如果案例类在家庭外部类型中声明,如何调用它的通用复制函数?

这是由路径依赖类型引起的scala问题:考虑到我有一个家庭类型:

如果我想Outer#Inner.copy()在实例Outer未知时调用:

我会遇到编译错误。因为 src.copy() 的类型签名附加到其外部实例。

绕过这个的一种方法是手动提取外部实例:

这可以编译成功,但asInstanceOf[]显然是一个黑客制品,应该被删除。

在惯用的 scala 中,实现相同目标的最佳方法是什么,同时让 scala 编译器自动推断 的存在outer,并在没有盲目类型转换的情况下生成正确的类型签名?

0 投票
2 回答
117 浏览

scala - 在scala中,如果案例类在家庭外部类型中声明,如何调用它的通用复制函数?- 第2部分

这是第 1 部分的后续问题:

在scala中,如果案例类在家庭外部类型中声明,如何调用它的通用复制函数?

在第 2 部分中,家庭类的定义变得稍微复杂一些:

所以旧技巧不再起作用,上面的编译错误如下:

在这种情况下如何编译?

0 投票
0 回答
62 浏览

scala - 在scala中,如何消除家庭类中依赖类型的“未检查,因为它已被擦除”错误

考虑以下类:

在编译时,它给出了以下警告:

这个问题比泛型集合类中的匹配更困难(可以通过包含 ClassTag 轻松解决,请参阅How do I get around type erasure on Scala?或者,为什么我不能获取集合的类型参数?)。在这种情况下,类型“Type”取决于路径 this.universe,没有可以轻松表示的 ClassTag。那么我应该如何指示编译器以另一种方式看待呢?

0 投票
1 回答
117 浏览

scala - 在 scala 2 中,可以使用宏或任何语言特性来重写所有子类中的抽象类型具体化机制吗?斯卡拉 3 怎么样?

在 scala 2 中已知宏是严格本地的,并且只在定义类时执行一次。当与抽象类型结合时,这一特性似乎特别弱,因为将抽象类型转换为具体类型的过程通常会绕过宏并使用其自己的原始规则。

下面的测试代码中展示了一个反直觉结果的简单示例:

如果执行,kk的类型变成:

糟糕,类型 AA 完全被忽略了,因为implicitly[TypeTag[this.type]]它由内置宏隐式支持,该宏仅在定义 BB 时执行一次,而不是在定义 AA 并具体化实际时执行kk.this.type。我发现它非常笨拙并且容易导致一些其他特性(例如模式匹配、类型 lambda)由于运行时类型擦除而降级。

我想编写/使用语言扩展,例如制作TypeTag[this.type]AA 的子类型,而不引入运行时开销和超出范围的上下文对象(因此,没有隐含)。我怎样才能以最少的黑客攻击做到这一点?我对编译器扩展和宏等非常核心的解决方案持开放态度,但显然首选可以顺利转移到 scala 3/dotty 的优雅解决方案。

PS 似乎有点“内联/编译时”功能已经部分实现了我的设想。这是正确的印象吗?

0 投票
1 回答
105 浏览

scala - 在 Scala 2.13 中。如何在宏中可靠地记录信息/警告/错误?

我正在编写一个宏,可以在编译期间记录一条短消息,使用 scala 2.13 的模式匹配和常量类型特性:

在测试的时候,我发现直接调用宏大部分时间都是有效的:

(这会生成正确的编译消息):

...但如果是隐式宏模式的一部分(https://docs.scala-lang.org/overviews/macros/implicits.html),则很少起作用:

所以我的问题是:

  • 调用 c.info/warning/error 是登录编译时的正确方法吗?

  • 如果是这样,为什么它们永远不会作为隐式宏模式的一部分?

非常感谢您的建议!

更新 1刚刚在https://github.com/fthomas/singleton-ops/blob/204195838ada34de7e453401fb06810ace2c99b0/src/main/scala/singleton/ops/impl/GeneralMacros.scala#L102找到了一个案例(错误)的解决方案

这是一个复杂的 hack,它通过在隐式函数的定义上添加 @implicitNotFound 注释来工作。到目前为止,我不知道警告和信息案例有任何类似的解决方案。然而,更简单的解决方案始终是首选

0 投票
1 回答
68 浏览

scala - 在 scala 中,是否可以从 TypeTag 初始化单例对象?

假设我有一个带有 TypeTag 的类:

T如果T是单例类型,是否可以在运行时使用 TypeTag 来查找 的值?即:

我不确定此功能是否在 scala 反射中本地提供。因此,请尽可能建议任何库/黑客,而不更改课程的签名TypeViz

非常感谢您的意见。

0 投票
1 回答
125 浏览

scala - `Coder[P <: Product]`的Scala 2宏类型类派生以错误`P不带参数`结束

我是 Scala 2 Macros 的初学者(在我切换到 Dotty 之前),在尝试了无形类型类派生之后,我想更进一步,编写一个宏,可以为任何scala.Product没有它的类型生成类型类实例。

(为了举例,让我们忽略嵌套递归类型,所以我的目标是平面案例类。)

我的类型类是一个抽象类Coder[T](例如带有encode()/的特征decode())。

所以生成的代码为:

应该是这样的:

(删除了完全指定的类名以提高可读性)

在宏中,我尝试:

  • 检查weakTypeOf[P]
  • 遍历每个案例类构造函数字段(类型F
    • 隐式找到它们的类型类Coder[F]实例并将其添加到树中
    • 并将它们的encode()decode()表达式附加到有助于最终Coder[P]方法的树中。

但调用后出现错误sbt Test / compile

(在导入和隐式搜索方面有点挣扎,所以现在有中间private vals,并且 distinct 没用)

我相信来自这里但不完全理解编译器试图告诉我什么?

完整代码示例的链接可以在这里
找到 CI 错误的链接可以在这里找到。

0 投票
1 回答
68 浏览

scala - 在 scala 中,是否可以将函数定义为具有 pass-by-AST 参数,以便函数的输入 AST 可以按原样传递给宏?

我将使用 shapeless 库作为示例:

假设我想将illType函数包装在另一个函数中,我尝试了 2 种不同的方法来做到这一点:

(按价值)

(按名字)

所以它们都没有按预期工作。这在最新的 scala 或 dotty 中是否可行?