什么 Scala 3 语法可以匹配宏上下文中的类型及其类型参数?

2023-12-14

从 Scala 3 宏的上下文来看:

  def aMacroImpl[T](using Type[T], Quotes): Expr[SpecialMap[_, _, _]] = {
    import quotes.reflect._
    val TRepr: TypeRepr = TypeRepr.of[T]
    val TSym: Symbol = TRepr.typeSymbol
    val SrtdMapSym: Symbol = TypeRepr.of[scala.collection.SortedMap].typeSymbol

    TSym.declaredFields.map{ f => TRepr.memberType(f) }.collect {
      case fieldTyepRepr if fieldTyepRepr.derivesFrom(SrtdMapSym) =>
        val fieldType = Inferred(fieldTyepRepr).tpe.asType
        fieldType match {
          ////////////////////////////////////////////////////////////
          case ... => // <-- This line is the subject of the question.
          ////////////////////////////////////////////////////////////
            '{SpecialMap.apply[k, v, sm](/* omitted for brevity*/)}
        }
    }
  }

  // More context.
  object SpecialMap {
    import scala.collection.mutable.Builder
    def apply[K, V, SM <: SortedMap[K, V]](bldr: Builder[(K, V), SM]): SpecialMap[K, V, SM] = {
      SpecialMap[K, V, SM](bldr.result)
    }
  }
  case class SpecialMap[K, V, SM <: SortedMap[K, V]](wrapedMap: SM)

什么样的语法可以代替“...在上面的代码片段中,它可以匹配给定的 SortedMap 类型,以便它可以检索所有三个类型参数:k、v 和 sm?

询问者已经尝试过以下方法:

  1. 不完整的解决方案:
/*a*/  case '[sm] => // provides sm, but not k or v

/*b*/  case '[SortedMap[k, v]] => // provides k and v but not sm
  1. 直接编译错误:
/*a*/  case '[sm[k, v]] => // sm$given1.Underlying does not take type parameters

/*b*/  case '[_[k, v]] => // ']' expected, but '[' found 

/*c*/  case 'sm[k, v] => /* symbol literal 'sm is no longer supported, use a string literal
"sm" or an application Symbol("sm") instead, or enclose in braces '{sm} if you want a
quoted expression. For now, you can also `import language.deprecated.symbolLiterals` to
accept the idiom, but this possibility might no longer be available in the future. */

/*d*/
  import language.deprecated.symbolLiterals
  fieldType match {
    case 'sm[k, v] => // '=>' expected, but '[' found

/*e*/
  type SM[k, v] = fieldType match {  // Not found: type fieldType
    case '[sm] => Type[sm]
    case _ => quotes.reflect.report.errorAndAbort("uh oh")
  }

/*h*/
  case '[sm] =>
   type SM[k1, v1] <: SortedMap[k1, v1] = Type[sm] // cannot combine bound and alias

/*f*/
case '[sm] =>
  type SM = Type[sm]
  fieldType match {
    case '[SM[k, v]] => // SM does not take type parameters
  1. 微妙的编译器错误:
// Examples in this snippet lose the association between k, v, sm, and SortedMap[k,v].

// All yield the following error:
// Type argument sm does not conform to upper bound collection.SortedMap[k, v]

/*a*/
  case '[SortedMap[k, v]] =>
    fieldType match {
      case '[sm] if TypeRepr.of[sm].derivesFrom((TypeRepr.of[SortedMap[k, v]]).typeSymbol) =>
        '{SpecialMap.apply[k, v, sm](/***/)} // ... sm does not conform ...

/*b*/
  fieldType match {
    case '[sm] =>
      fieldType match {
      case '[SortedMap[k, v]] if TypeRepr.of[sm].derivesFrom((TypeRepr.of[SortedMap[k, v]]).typeSymbol) =>
        '{SpecialMap.apply[k, v, sm](/***/)} // ... sm does not conform ...

/*c*/
  (fieldType, fieldType) match {
    case ('[sm], '[SortedMap[k, v]]) =>
      '{SpecialMap.apply[k, v, sm](/***/)} // ... sm does not conform ...

/*d*/
  fieldType match {
    case '[sm1] =>
      type SM[k1,v1] = Type[sm1]
      fieldType match {
        case '[SM[k, v]] =>
          '{SpecialMap.apply[k, v, SM[k, v]](/***/)} // ... SM does not conform ...

/*e*/
  fieldType match {
    case '[sm1] =>
    fieldType match {
      case '[SortedMap[k, v]] =>
        type SM[k,v] = Type[sm1]
        '{SpecialMap.apply[k, v, SM[k, v]](/***/)}  // ... SM does not conform ...

当然,显式编写从 SortedMap 派生的每个已知具体类适用于任何特定项目,但库应该容纳 SortedMap 特征的未知继承者。

有没有办法捕获所有三种类型参数及其相互依赖的关系?

谢谢您的考虑。


我想你不能保证在宏的编译时

val fieldTypeTree = Inferred(fieldTyepRepr).tpe
val fieldType = fieldTypeTree.asType

(fieldType, fieldTypeTree.baseType(SrtdMapSym).asType) match {
  case ('[sm], '[SortedMap[k, v]]) =>
    '{SpecialMap.apply[k, v, sm](???)}
}

k, v, sm满足sm <: SortedMap[k, v].

所以如果你不能通过引用构建树'{SpecialMap.apply[k, v, sm](???)},你应该手动构建它。

或者您可以返回'{SpecialMap.apply[k, v, sm & SortedMap[k, v]](???)}.


也许像下面这样的事情是可能的

val fieldTypeTree = Inferred(fieldTyepRepr).tpe
val fieldType = fieldTypeTree.asType
val parentType = fieldTypeTree.baseType(SrtdMapSym).asType

(fieldType, parentType) match {
  case ('[ft], '[pt]) =>
    '{foo[ft, pt]} match
      case '{
        type k
        type v
        type sm <: SortedMap[`k`, `v`]
        foo[`sm`, SortedMap[`k`, `v`]]
      } =>
        '{SpecialMap.apply[k, v, sm](???)}
  }

// outside def aMacroImpl, otherwise "access to method foo from wrong staging level"
def foo[A, B] = ???

由于某种原因,这仍然没有进行类型检查:https://scastie.scala-lang.org/DmytroMitin/ZbtQWZFkTma6MlFM72x5Dg/2

可能是因为错误:

引用内未推断类型绑定(类型变量转义?)

模式匹配类型变量不推断边界

断言失败:在酸洗具有类型边界的引用时无法解析符号

也可以看看:

https://docs.scala-lang.org/scala3/guides/macros/quotes.html#type-variables-in-quoted-patterns

在某些情况下,我们需要定义一个被多次引用或具有某种类型界限的模式变量。为了实现这一点,可以使用以下命令在模式开始处创建模式变量type t带有类型模式变量。

scala 3中的fuseMap宏

Scala 3 宏中的显式类型转换

获取Scala3宏中的类型信息

将内联可变参数转换为通用元组

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

什么 Scala 3 语法可以匹配宏上下文中的类型及其类型参数? 的相关文章

随机推荐

  • SICP 3.52 延迟 CDR

    练习3 52 define sum 0 define accum x set sum x sum sum 1 define seq stream map accum stream enumerate interval 1 20 2 defi
  • 在 php 中打印到 Zebra 打印机

    正在寻找使用 RAW 端口 9100 从 php 网页打印到 zebra IP 打印机的正确代码 有谁知道这是否可行 我需要将 ZPL 格式输出的字符串直接发送到 ZM400 标签打印机 我到处搜索 找到的最接近的是 使用php直接打印到网
  • 如何使下拉菜单自动完成消失 onblur 或单击 jquery 外部?

    下面是被调用以在搜索框中显示自动完成功能的函数 我希望自动完成功能在模糊或单击搜索框外部时消失 请告诉我应该在此函数中添加什么以使自动完成功能消失点击外面时向下消失 function hideLoader sub cont fadeIn 1
  • password_hash 到底是如何工作的?

    我试图理解密码哈希值充分以便能够向审核员解释 根据我对答案的寻找 我了解到password hash 函数是一个包装器crypt 在阅读 PHP 手册时预定义常量我看到它使用PASSWORD BCRYPT作为默认整数值 基本上它使用CRYP
  • PDO SQLite查询零结果问题

    我环顾四周 但似乎找不到任何有关此的信息 我不确定这是我的代码的问题还是内存 SQLite 数据库和 PDO 的已知问题 基本上 在将单行插入内存 SQLite 数据库表后 我希望与插入项不匹配的查询返回零行 但是 以下代码给出了一行 fa
  • 是否可以将 DataTable 作为 TextBox 中的 AutoCompleteSource? (C#)

    是否可以将 DataTable 作为 TextBox 中的 AutoCompleteSource C Jared 是正确的 如果不进行一些操作 就无法直接绑定 以下是使用 LINQ 数据集扩展检索字段作为自动完成源的示例 DataTable
  • Windows MIrror 驱动程序 远程显示驱动程序 VNC 服务器 Windows 8

    我正在开发远程桌面服务器的驱动程序 像 UltraVNC 内部协议 之类的东西 首先我发现 Windows 8 不支持镜像驱动程序 作为远程显示驱动程序的 DDI 的唯一子集 1 这是否意味着我需要为 Windows 8 实施远程显示驱动程
  • JavaScript:输入按键

    早上好 I am using java script in each page to trigger the Enter key press Event inside the textbox It is working fine Now i
  • 通过 Azure Powershell 设置 Azure 网站的主机名

    我正在尝试使用 PowerShell 将主机分配给 Azure 网站实例 我已验证要添加的域 主机是否有效 甚至转到 Azure 门户以验证其将新域识别为有效 但由于某种原因 下面的脚本没有像我认为应该的那样设置主机名 当我在为主机名设置新
  • 在运行时自动从 PowerShell 作业中提取数据

    当我试图做一些很可能超出 PowerShell 范围的事情时 我似乎遇到了障碍 我有一个主窗体脚本 它协调了我的大部分功能 但我需要另一个脚本来打开侦听器 system Net Sockets Udpclient Receive 并在整个程
  • 在 AWS Lambda 上安装新字体

    我正在 AWS Lambda 上安装 Imagemagick 但 Imagemagick 通常使用的字体似乎未预安装 如何添加其他字体 以下是我刚刚使用 pandoc xelatex 在 AWS Lambda 上处理自定义字体的工作 我假设
  • 使用 GDB 更改 JVM 中的变量值

    目前我有一个简单的Java程序 public class Test public static void main String args boolean test true while test System out println He
  • JavaFX 中滑块拇指的坐标

    有一些方法可以知道滑块拇指的位置JavaFX Use getBoundsInParent and a lookup Bounds bounds slider lookup thumb getBoundsInParent 您可能需要apply
  • 错误:SQLSTATE[HY000] [2002] 没有这样的文件或目录

    我知道这类问题可能被问过几次 但它们都与 laravel 有关 在我的例子中 这是没有框架的普通 php 我有一个表单 可以从用户那里收集表单并将其保存到数据库中 但我不断收到有关 MYSQL 的错误Error SQLSTATE HY000
  • Laravel 和谷歌地图:foreach 纬度/经度显示标记或地图

    我有一个带有纬度和经度字段的表位置 对于每个位置 我想要一个新地图 或者更好的新标记 它使用表位置中的纬度和经度在地图上显示城市 控制器的索引动作 public function index locations Location all l
  • 具有九个补丁项目背景问题的 ListView

    警告 此问题中的 XML 是错误的 请先阅读答案 然后再混淆 我已经用头撞墙有一段时间了 以下帖子阐明了该主题 但未能解决我的问题 Android ListView 状态列表不显示默认项目背景 and 通过自定义选择器的 ListView
  • Laravel 应用程序关闭时会触发什么事件?

    具体来说 我正在做的是在我的 AppServiceProvider gt boot 方法中 我正在创建一个单例类 如下所示 class AppServiceProvider extends ServiceProvider public fu
  • 从内部块返回值(Objective-C)

    我一直在尝试从中获取价值inside现在已经阻塞了几个小时 我不明白如何在完成时使用处理程序以及几乎所有内容 这是我的代码 void downloadUserID void NSString result handler Now redir
  • 如何查看在 Visual Studio 中预处理后的 C/C++ 源文件?

    假设我有一个包含许多预处理器指令的源文件 是否可以看到预处理器完成后的样子 cl exe是 Microsoft Visual C 的命令行界面 具有三个不同的选项用于输出预处理文件 因此前面有关 Visual C 的响应不一致 E 预处理到
  • 什么 Scala 3 语法可以匹配宏上下文中的类型及其类型参数?

    从 Scala 3 宏的上下文来看 def aMacroImpl T using Type T Quotes Expr SpecialMap import quotes reflect val TRepr TypeRepr TypeRepr