如何在 Scala 3 中证明 `Tuple.Map[H *: T, F] =:= (F[H] *: Tuple.Map[T, F])`

2023-11-29

我正在尝试编写一个包含元组类型给定实例的特征(是的,我知道summonAll存在):

trait TupleInstances[C[_], T <: Tuple] {
  val instances: Tuple.Map[T, C]
}

given[C[_]]: TupleInstances[C[_], EmptyTuple] with {
  val instances = EmptyTuple
}

inline given[C[_], H, T <: Tuple] (using ch: C[H], ti: TupleInstances[C, T]): TupleInstances[C, H *: T] with {
  val instances: Tuple.Map[H *: T, C] = ch *: ti.instances
}

并得到错误

 val instances: Tuple.Map[H *: T, C] = ch *: ti.instances
  |                                        ^^^^^^^^^^^^^^^^^^
  |               Found:    C[H] *: Tuple.Map[T, C]
  |               Required: Tuple.Map[H *: T, C]
  |
  |               Note: a match type could not be fully reduced:
  |
  |                 trying to reduce  Tuple.Map[T, C]
  |                 failed since selector  T
  |                 does not match  case EmptyTuple => EmptyTuple
  |                 and cannot be shown to be disjoint from it either.
  |                 Therefore, reduction cannot advance to the remaining case
  |
  |                   case h *: t => C[h] *: scala.Tuple.Map[t, C]

所以本质上我需要向所有人证明这一点F[_], Tup:

Tuple.Map[Tup, F] =:= (F[Tuple.Head[Tup]] *: Tuple.Map[Tuple.Tail[Tup], F])

我该如何去做呢?


首先,TupleInstances[C[_], EmptyTuple] (for C[_] and trait TupleInstances[C[_], T <: Tuple]) 是不正确的

Type argument C[?] does not have the same kind as its bound [_$1]

正确是更高尚的TupleInstances[C, EmptyTuple] or TupleInstances[C[*], EmptyTuple] (with scalacOptions += "-Ykind-projector") or TupleInstances[[t] =>> C[t], EmptyTuple]. TupleInstances[C[_], EmptyTuple]最终应该意味着相同,但目前它意味着存在TupleInstances[C[?], EmptyTuple].

多态方法适用于 lambda 类型,但不适用于 Scala 3 中的类型通配符

高级类型参数中下划线的使用规则

第二,

  • 匹配类型,以及

  • 类型类

是在 Scala 3 中执行类型级计算的两种不同方法(如 Scala 2 中的类型投影和类型类,或者 Haskell 中的类型族和类型类)。如果你想混合使用它们,一些极端情况是可能的。

您可以再添加一项约束

trait TupleInstances[C[_], T <: Tuple]:
  def instances: Tuple.Map[T, C]
object TupleInstances:
  given[C[_]]: TupleInstances[C, EmptyTuple] with
    val instances = EmptyTuple

  given[C[_], H, T <: Tuple](using
    ch: C[H],
    ti: TupleInstances[C, T],
    ev: (C[H] *: Tuple.Map[T, C]) =:= Tuple.Map[H *: T, C] // <-- HERE!!!
  ): TupleInstances[C, H *: T] with
    val instances: Tuple.Map[H *: T, C] = ch *: ti.instances

或者使用summonFrom and inline

import scala.compiletime.summonFrom

trait TupleInstances[C[_], T <: Tuple]:
  def instances: Tuple.Map[T, C]
object TupleInstances:
  given[C[_]]: TupleInstances[C, EmptyTuple] with
    val instances = EmptyTuple

  given[C[_], H, T <: Tuple](using
    ch: C[H],
    ti: TupleInstances[C, T]
  ): TupleInstances[C, H *: T] with
    inline def instances: Tuple.Map[H *: T, C] =
      summonFrom {
        case _: ((C[H] *: Tuple.Map[T, C]) =:= Tuple.Map[H *: T, C]) =>
          ch *: ti.instances
      }

Scala 并不是一个真正的定理证明器。它可以检查C[H] *: Tuple.Map[T, C] =:= Tuple.Map[H *: T, C]对于具体的C, H, T但不能任意

如何在 Scala 2.13 中定义自然数归纳法?

此外,您还应该重新考虑是否要根据匹配类型而不是类型类来制定整个逻辑

import scala.compiletime.{erasedValue, summonInline}

inline def tupleInstances[C[_], T <: Tuple]: Tuple.Map[T, C] = erasedValue[T] match
  case _: EmptyTuple => EmptyTuple
  case _: (h *: t)   => summonInline[C[h]] *: tupleInstances[C, t]

或者您想根据类型类而不是匹配类型来制定整个逻辑

trait TupleInstances[C[_], T <: Tuple]:
  type Out <: Tuple
  def instances: Out
object TupleInstances:
  given[C[_]]: TupleInstances[C, EmptyTuple] with
    type Out = EmptyTuple
    val instances = EmptyTuple

  given[C[_], H, T <: Tuple](using
    ch: C[H],
    ti: TupleInstances[C, T]
  ): TupleInstances[C, H *: T] with
    type Out = C[H] *: ti.Out
    val instances = ch *: ti.instances

在Scala 3中,如何替换已删除的通用类型投影?

Dotty 提供什么来替代类型投影?

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

如何在 Scala 3 中证明 `Tuple.Map[H *: T, F] =:= (F[H] *: Tuple.Map[T, F])` 的相关文章

随机推荐

  • 将图例宽度设置为 100% 绘图宽度

    无论实际尺寸如何 如何将图例高度或宽度设置为绘图高度 宽度的 100 library ggplot2 ggplot iris aes Petal Width Sepal Width color Petal Length geom point
  • jquery加载函数问题

    我正在尝试使用 jquery 加载函数在按下按钮时将转换为 DAE 文件的 3D 模型加载到目标 div 中 然而 当按下按钮时 屏幕上会出现与文件相关的大量数字 而不是模型 这是问题的屏幕截图 如果不可能做到这一点 我还想知道是否可以使用
  • Java 字符串连接

    我的 java 代码有问题 我昨天问了同样的问题 我得到了答复 但很抱歉这是我的错 我的问题不清楚 我的代码如下所示 for i 0 i lt geo getTargets length i if geo getTargets i getT
  • 如何以编程方式打开受密码保护的 PDF 文件?

    Adobe IFilter 不提供提供密码来打开受密码保护的 PDF 文件的机制 因此它不能用于打开受密码保护的文件 我想知道 是否有一种相对简单的方法来以编程方式检索 PDF 文件中的实际加密数据 使用标准加密 API 对其进行解密 然后
  • 如何在图形和子图周围添加边框或框架

    我想创建这样的图像 但我无法将各个图放入框架内 图形和坐标轴都有一个 patch 属性 它是构成背景的矩形 因此 设置图形框架非常简单 import matplotlib pyplot as plt fig axes plt subplot
  • jQuery 和 AJAX 登录表单

    我正忙于开发一个网站 右上角有一个登录框 我希望用户能够在同一页面上登录 而无需刷新 好的 我已经完成了该部分的工作 但我仍然在登录后过程中苦苦挣扎 我的外观如下 HTML li class login li PHP session sta
  • 使用jquery动态改变背景颜色

    现在我的页面的一部分有一个对象列表 当您将鼠标悬停在它们上方时 背景会变成浅黄色 并在鼠标移开时恢复为白色 我希望其中一个对象在满足条件时变成绿色背景 如果不满足则恢复正常 我遇到这种情况有一个问题 如果满足条件 它会改变颜色 如果不满足
  • 如何避免在 Excel 文件下载过程中出现 Response.End()“Thread was being aborted”异常

    我尝试将数据集转换为 Excel 并下载该 Excel 我得到了所需的 Excel 文件 但是每次 Excel 下载都会引发 System Threading ThreadAbortException 如何解决这个问题 请帮我 我在我的 a
  • 手机上测试Admob时DEVICE_ID_EMULATOR和TEST_EMULATOR的区别

    使用 TEST EMULATOR 和 DEVICE ID EMULATOR 有什么区别 我想在我的手机上测试admob广告系统 NOT在 PC 上的模拟器上 AdRequest ad new AdRequest Builder addTes
  • 如何更改进度条的颜色

    我想改变颜色最后更新文本 默认情况下它是黑色的 有没有办法引入一些代码来改变我为栏文本所做的文本颜色 帮我介绍一下缺少的代码 div span 2 span div div div Last updated 7 01 2013 progre
  • 从另一个 php 文件调用未定义的函数

    好吧 这就是我的代码的样子 索引 php require once WebsiteRoot include testfile php TestFunction include testfile php function TestFuncti
  • QLPreviewController 视图

    我只是想访问 QLPreviewController view 事实上 我想捕获其视图上的点击事件以显示 隐藏工具栏等 我正在尝试 QLPreviewController qlpc QLPreviewController new qlpc
  • 如何进行通用订单[重复]

    这个问题在这里已经有答案了 我有一个数据库作为数据框 我想对所有列进行排序 但保持元素之间的关系 例如 如果我执行以下操作 gt DF A B C D 1 11 2 432 4 2 11 3 432 4 3 13 4 241 5 4 42
  • 使用 mongoose model.find() 获取仅 1 个字段的所有条目

    我尝试使用 model find 的不同变体 但没有一个能达到我想要的效果 下面的代码是我正在使用的代码 但它显示每个字段 而我只想要 iframe 字段 app get api videos function req res Video
  • 如何将选择值存储到 php 变量中

    我有一个简单的下拉选择菜单 div div
  • 将匹配多个批量输入的 LINQ 表达式 [重复]

    这个问题在这里已经有答案了 如何编写匹配多个批量输入的 LINQ 表达式 这是我的数据库表 Members Division Department 1 3 4 9 5 1 6 3 9 2 我想选择标有 的成员 这是我的输入 int divi
  • JPA + Spring 异常后回滚事务

    我正在使用 Spring 和 JPA 下面带有 HIbernate 当抛出 PersistenceException 时 我想捕获它并返回错误消息 以便它不会传播给调用者 Transactional public String save O
  • 空引用 - 任务ContinueWith()

    对于以下代码段 NET v4 0 30319 我在第二个延续中收到如下所示的空引用异常 最有趣的是 这个问题只发生在 8GB RAM 的机器上 但其他用户有 16GB 或更多内存 他们没有报告任何问题 这是一个非常间歇性的问题 这让我怀疑垃
  • 对 URL 进行编码/解码

    在 Go 中编码和解码整个 URL 的推荐方法是什么 我知道这些方法url QueryEscape and url QueryUnescape 但它们似乎并不正是我正在寻找的 具体来说 我正在寻找像 JavaScript 这样的方法enco
  • 如何在 Scala 3 中证明 `Tuple.Map[H *: T, F] =:= (F[H] *: Tuple.Map[T, F])`

    我正在尝试编写一个包含元组类型给定实例的特征 是的 我知道summonAll存在 trait TupleInstances C T lt Tuple val instances Tuple Map T C given C TupleInst