在scala中,如何使类型类适用于Aux模式? - 第2部分

2024-01-03

这是以下问题的后续问题:在scala中,如何使类型类适用于Aux模式? https://stackoverflow.com/questions/65838535/in-scala-how-to-make-type-class-working-for-aux-pattern

考虑以下示例:

  trait Base {

    type Out
    def v: Out
  }

  object Base {

    type Aux[T] = Base { type Out = T }
    type Lt[T] = Base { type Out <: T }

    class ForH() extends Base {

      final type Out = HNil

      override def v: Out = HNil
    }

    object ForH extends ForH
  }

  trait TypeClasses {

    class TypeClass[B]

    def summon[B](b: B)(implicit ev: TypeClass[B]): TypeClass[B] = ev
  }

  object T1 extends TypeClasses {

    implicit def t1: TypeClass[Base.Aux[HNil]] = new TypeClass[Base.Aux[HNil]]

    implicit def t2: TypeClass[Int] = new TypeClass[Int]
  }

  object T2 extends TypeClasses {

    implicit def t1[T <: Base.Aux[HNil]]: TypeClass[T] = new TypeClass[T]
  }

  object T3 extends TypeClasses {

    implicit def t1[
        H <: HList,
        T <: Base.Lt[H]
    ]: TypeClass[T] = new TypeClass[T] {

      type HH = H
    }
  }

  object T4 extends TypeClasses {

    implicit def t1[
        H <: HList,
        T <: Base.Aux[H]
    ]: TypeClass[T] = new TypeClass[T] {

      type HH = H
    }
  }

  it("No Aux") {

    val v = 2

    T1.summon(v) // works
  }

  it("Aux1") {

    val v = new Base.ForH()

    T1.summon(v) // oops
    T1.summon(Base.ForH) // oops

    val v2 = new Base.ForH(): Base.Aux[HNil]
    T1.summon(v2) // works!
  }

  it("Aux2") {

    val v = new Base.ForH()

    T2.summon(v) // works
    T2.summon(Base.ForH) // works

    val v2 = new Base.ForH(): Base.Aux[HNil]
    T2.summon(v2) // works
  }

  it("Aux3") {

    val v = new Base.ForH()

    T3.summon(v) // oops
    T3.summon(Base.ForH) // oops

    val v2 = new Base.ForH(): Base.Aux[HNil]
    T3.summon(v2) // oops
  }

  it("Aux4") {

    val v = new Base.ForH()

    T4.summon(v) // oops
    T4.summon(Base.ForH) // oops

    val v2 = new Base.ForH(): Base.Aux[HNil]
    T4.summon(v2) // oops
  }

的所有实现TypeClasses包含其底层的隐式范围TypeClass,其中,T1是最简单和具体的定义ForH,不幸的是它不起作用。 @Dan Simon 提出了一项改进(在T2),它使用类型参数来让spark编译器发现ForH <:< Base.Aux[HNil]

现在想象一下,我想扩展@Dan Simon 的解决方案,以便类型类适用于所有类,例如ForH对于不同类型的 HList(HNil 的超级特征)。 2 个自然扩展位于T3 & T4分别。

不幸的是,它们都不起作用。这T4可以用以下事实来解释ForH <:< Aux[HList]是无效的,但是T3不能用这个借口。另外,也没有办法改进它才能编译成功。

为什么类型类召唤算法在这种情况下失败了?应该怎样做才能使类型类模式真正起作用?


Again, T1.summon(v)无法编译,因为T1.t1不是候选者,手动解决T1.summon(v)(T1.t1)不编译。

For T3 and T4 T3.t1[HNil, Base.ForH], T4.t1[HNil, Base.ForH]将成为候选人

T3.summon(v)(T3.t1[HNil, Base.ForH]) // compiles
T4.summon(v)(T4.t1[HNil, Base.ForH]) // compiles

但问题是H首先被推断并且被推断为Nothing but t1[Nothing, Base.ForH]不满足类型限制。

所以问题不在于隐式解析算法,没关系,问题在于类型推断(我们都知道它在 Scala 中相当弱)。

你可以预防H推断得太快Nothing如果你修改T3.t1, T4.t1

object T3 extends TypeClasses {    
  implicit def t1[
    H <: HList,
    T <: Base/*.Lt[H]*/
  ](implicit ev: T <:< Base.Lt[H]): TypeClass[T] = new TypeClass[T] {
    type HH = H
  }
}

object T4 extends TypeClasses { 
  implicit def t1[
    H <: HList,
    T <: Base/*.Aux[H]*/
  ](implicit ev: T <:< Base.Aux[H]): TypeClass[T] = new TypeClass[T] {
    type HH = H
  }
}

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

在scala中,如何使类型类适用于Aux模式? - 第2部分 的相关文章

  • 通用 scala 函数,其输入是变量数量的函数

    我想定义一个函数f需要另一个函数g 我们需要g采取采取n双打 对于某些固定n 并返回一个 Double 函数调用f g 应该返回具体值n 例如 f Math max 2因为 Math sin 具有类型 Double Double gt Do
  • 如何在 Apache Spark 中通过 DStream 使用特征提取

    我有通过 DStream 从 Kafka 到达的数据 我想进行特征提取以获得一些关键词 我不想等待所有数据的到达 因为它是可能永远不会结束的连续流 所以我希望以块的形式执行提取 如果准确性会受到一点影响 对我来说并不重要 到目前为止 我整理
  • Akka Stream Graph 恢复问题

    我创建了一个图表来并行化具有相同输入的两个流 这些流产生 Future Option Entity 如果 flowA 失败 我想返回 Future None 但恢复似乎没有被调用 val graph Flow Input Future Op
  • Scala 宏的位置怎么了?

    我试图获取宏参数的原始输入字符串 但返回的位置似乎有点偏离 考虑这个宏 例如 object M import scala reflect macros Context import language experimental macros
  • 更改 build.sbt 自定义任务中的版本

    我在 build sbt 中定义了一个自定义任务 val doSmth taskKey Unit smth doSmth version 1 0 SNAPSHOT 但它不会改变版本 我真正想要的是自定义 sbt 发布任务 它将始终将相同的版
  • 可选择将项目添加到 Scala 映射

    我正在寻找这个问题的惯用解决方案 我正在构建一个valScala 不可变 Map 并希望有选择地添加一项或多项 val aMap Map key1 gt value1 key2 gt value2 if condition key3 gt
  • 规范化且不可变的数据模型

    Haskell如何解决 规范化不可变数据结构 问题 例如 让我们考虑一个表示前女友 男友的数据结构 data Man Man name String exes Woman data Woman Woman name String exes
  • Scala:什么是 CompactBuffer?

    我试图弄清楚 CompactBuffer 的含义 和迭代器一样吗 请解释其中的差异 根据 Spark 的文档 它是 ArrayBuffer 的替代方案 可以提供更好的性能 因为它分配的内存更少 以下是 CompactBuffer 类文档的摘
  • andThen 类型不匹配的 Scala 链接函数

    我有一堆函数可以清理文本并将它们分成单词 最小的例子 val txt Mary had a little nlamb val stopwords Seq a def clean text String String text replace
  • 解决“Show”类型类实例的隐式问题

    我正在努力使Gender实施Show类型类 scala gt trait Gender extends Show Gender defined trait Gender scala gt case object Male extends G
  • 具有继承类型的 Aux 模式推理失败

    我有一个复杂的玩具算法 我希望纯粹在类型级别上表示 根据饮食要求选择当天菜肴的修改 对卷积表示歉意 但我认为我们需要每一层才能达到我想要使用的最终界面 我的代码有一个问题 如果我们表达一个类型约束Aux 模式生成的类型基于另一个泛型类型 它
  • Akka-Streams 收集数据(Source -> Flow -> Flow (collect) -> Sink)

    我对 Scala 和 Akka 完全陌生 我有一个简单的 RunnableFlow Source gt Flow do some transformation gt Sink runForeach 现在我想要这样的东西 Source gt
  • 为什么自类型类可以声明类

    我知道 Scala 只能混合特征 这对于依赖注入和蛋糕模式是有意义的 我的问题是为什么我仍然可以声明一个需要另一个 类 但不需要特征的类 Code class C class D self C gt 这仍然编译成功 我认为它应该编译失败 因
  • 如何在 sbt 控制台中加载 scala 文件? [复制]

    这个问题在这里已经有答案了 可能的重复 将 Scala 文件加载到解释器中以使用函数 https stackoverflow com questions 7383436 load scala file into interpreter to
  • 获取SettingKey[T]的值

    我正在开发一个用于文档生成的插件 我想将所有生成的文件输出到我选择的目录中 该目录可以是SBT的子目录target目录 如下 val newTargetDirectory SettingKey File document target di
  • Spark scala 模拟 Spark.implicits 用于单元测试

    当尝试使用 Spark 和 Scala 简化单元测试时 我使用 scala test 和mockito scala 以及mockito Sugar 这只是让你做这样的事情 val sparkSessionMock mock SparkSes
  • Kafka 分区键无法正常工作

    我正在努力解决如何正确使用分区键机制的问题 我的逻辑是设置分区号为3 然后创建三个分区键为 0 1 2 然后使用分区键创建三个KeyedMessage 例如 KeyedMessage 主题 0 消息 KeyedMessage 主题 1 消息
  • 使用 Akka 1.3 的 actor 时,我需要注意生产者-消费者速率匹配吗?

    使用 Akka 1 3 时 我是否需要担心当生成消息的 Actor 生成消息的速度比使用消息的 Actor 的处理速度快时会发生什么 如果没有任何机制 在长时间运行的进程中 队列大小将增大以消耗所有可用内存 The doc http doc
  • 了解 Spark 中的 DAG

    问题是我有以下 DAG 我认为当需要洗牌时 火花将工作划分为不同的阶段 考虑阶段 0 和阶段 1 有些操作不需要洗牌 那么为什么 Spark 将它们分成不同的阶段呢 我认为跨分区的实际数据移动应该发生在第 2 阶段 因为这里我们需要cogr
  • 如何调用 Scala 抽象类型的构造函数?

    我试图弄清楚如何调用 Scala 抽象类型的构造函数 class Journey val length Int class PlaneJourney length Int extends Journey length class BoatJ

随机推荐

  • 如何从 Pandas DataFrame 制作分组条形图[重复]

    这个问题在这里已经有答案了 如何使用 pyplot 绘制此数据框 Team Boys Girls 0 Sharks 5 5 1 Lions 3 7 data Team Sharks Lions Boys 5 5 Girls 5 6 df p
  • python中存储时间长度的类型是什么?

    我正在使用 total time datetime time int total time text replace h replace m split 0 int total time text replace h replace m s
  • 无法在 Terminal.app OSX 上使用 Ctrl+A 和 Ctrl+E(bash 键绑定)

    因此 由于某些奇怪的原因 我无法在 Terminal app 中的 bash 上使用 A 和 E 但是我可以使用 C R Y L 和所有其他键绑定 绑定 p显示 C a 行首 C e 行尾 所以我认为还有其他东西阻碍了这些键绑定 知道我该如
  • 为什么UTF-8使用多个字节来表示某些字符?

    我最近经历了一个article http www sitepoint com do you know your character encodings 关于字符编码 我对那里提到的某一点感到担忧 在第一张图中 作者展示了字符 它们在各种字符
  • 如何将下一个最大数字插入数据库

    我编写了一段 mysqli 代码 它将把值插入数据库 insertsql INSERT INTO Teacher TeacherId TeacherForename TeacherSurname TeacherEmail TeacherAl
  • 在 Objective-C 中打印多页

    我有一个像这样的打印功能 void sendToPrinter int code NSPrintInfo printInfo NSPrintInfo sharedInfo NSPrintOperation printOp NSMutable
  • 在 Windows 应用商店应用程序中获取 CoreDispatcher 的正确方法

    我正在构建一个 Windows 应用商店应用程序 并且有一些代码需要发布到 UI 线程 为此 我想检索 CoreDispatcher 并使用它来发布代码 似乎有几种方法可以做到这一点 First way Windows Applicatio
  • 如何从列的每一行中删除重复的字符?

    如何使用 R 从列的字符串中删除重复字符 例如 这是我的专栏 df lt data frame name c A a a b c d d d B a b b b f C d d d d D a a 还有我期待的专栏 df lt data f
  • 如何向 pagedown 添加自定义图像标签?

    我正在尝试复制原始内容img自定义标签的功能img将添加到 pagedown 转换器的标记 例如 我复制原始行为 image url 1 1 http lolink com gives img src http lolink com 变成一
  • Django_Socketio 和 Apache

    我对网络开发还很陌生 最近我一直在使用 Django 制作一个网站 我对在网站中实现 websocket 非常感兴趣 为了实现这一点 我使用了 django socketio 可在 git hub 上找到 https github com
  • Android缩放动画闪烁

    我的应用程序中有框架布局 在框架中我有 ImageView 和 TextView 我一直需要框架布局反弹 我用 xml 制作了这个动画
  • 通过ObjectOutputStream将LinkedList写入文本文件但输出是垃圾

    当我尝试将链接列表的内容写入文本文件时 出现输出错误 try FileOutputStream out new FileOutputStream ValidMovesMatrix txt ObjectOutputStream oout ne
  • 当用户确认“离开页面”时触发 javascript 函数

    我正在使用下面的代码来触发confirmExit 当用户尝试离开页面时函数 window onbeforeunload confirmExit function confirmExit return Are you sure you wan
  • RxJava。顺序执行

    在我的 Android 应用程序中 我有一个演示者 它处理用户交互 包含某种请求管理器 如果需要 可以通过请求管理器将用户输入发送到请求管理器 请求管理器本身包含服务器 API 并使用此 RxJava 处理服务器请求 我有一个代码 每次用户
  • Oracle 不同模式上的表名相同吗?

    是否可以在不同模式上使用相同的表名称 而在一个数据库中的表上使用不同的数据 我认为我不应该创建多个数据库 包含相同的表名 而应该创建多个模式 就像是 Schema 1 table A table B Schema 2 table B tab
  • 图解:python语言重路由问题测试

    贵公司有N服务器 信息通过连接从一台服务器流向另一台服务器 如果信息从服务器流出i到服务器j then 联系 i j 某些服务器连接 i i 是可能的 这意味着信息不会进一步流动 给定一个由 N 个整数组成的数组连接 您的任务是对连接数组值
  • 如何根据当前服务器找到最合适的缓冲区大小来读取或写入Stream

    我正在编写一个服务器 它将准备好并写入巨大的文件 数据库 我在很多地方使用了 Stream 读写函数 其中我使用 8192 作为缓冲区大小 我还从 TCP 套接字读取大量输入 我不知道将部署该服务的虚拟机的配置是什么 是否有任何内置函数可以
  • Lucene 通配符查询

    我有一个关于 Lucene 的问题 我有一个表单 并从中获取文本 我想在多个字段中执行全文搜索 假设我从输入中获取文本 textToLook 我有一个带有多个过滤器的 Lucene 分析器 其中之一是 lowerCaseFilter 因此当
  • lxml.objectify 和前导零

    当 objectify 元素打印在控制台上时 前导零会丢失 但它会保留在 text gt gt gt from lxml import objectify gt gt gt gt gt gt xml a b 01 b a gt gt gt
  • 在scala中,如何使类型类适用于Aux模式? - 第2部分

    这是以下问题的后续问题 在scala中 如何使类型类适用于Aux模式 https stackoverflow com questions 65838535 in scala how to make type class working fo