使用动态/具体类型初始化类型变量

2024-01-02

我正在学习 Scala,我试图创建一个类型类来解决“每种动物都吃食物,但食物的类型取决于动物”的问题。我有一个Eats具有上下文边界的类型类:

trait Eats[A <: Animal, B <: Edible]

object Eats {
    def apply[A, B]: Eats[A, B] = new Eats[A, B] {}
}

Animal and Edible是抽象类。 (减少)Animal界面看起来像这样

abstract class Animal {
    type This // concrete type
    def eat[A <: Edible](food: A)(implicit e: Eats[This, B]) = // ...
}

我的目标是允许以下形式的调用animal.eat(food)仅当存在给定类型的动物和食物的实例(范围内的隐式值)时。为此我创建了一个EatingBehaviour对象基本上包含所有关系的实例。例如为了声明牛吃草,我添加了这一行

implicit val cowEatsGrass = Eats[Cow, Grass]

类似于你会怎么写instance Eats Cow Grass在哈斯克尔。但是,现在我需要指定抽象类型This对于 Animal 类的所有子类型的签名Animal工作界面:

class Cow extends Animal { type This = Cow }

这是多余的。

因此我的问题:我可以以某种方式初始化类型变量吗This in Animal这样它总是反映具体类型,类似于我如何使用动态类型getClass?


如果传递第一个操作数,则不会出现该问题a: A到有机会推断外部可见类型的方法/类构造函数A:

trait Animal
trait Eats[A <: Animal, B <: Animal]

object Eats {
    def apply[A <: Animal, B <: Animal]: Eats[A, B] = new Eats[A, B] {}
}

implicit class EatsOps[A <: Animal](a: A) {
    def eat[B <: Animal](food: B)(implicit e: Eats[A, B]) = 
      printf(s"%s eats %s\n", a, food)
}

case class Cat() extends Animal
case class Bird() extends Animal
case class Worm() extends Animal

implicit val e1 = Eats[Cat, Bird]
implicit val e2 = Eats[Bird, Worm]

val cat = Cat()
val bird = Bird()
val worm = Worm()

// c eat c // nope
cat eat bird
// c eat w // nope

// b eat c // nope
// b eat b // nope
bird eat worm 

// w eat c // nope
// w eat b // nope
// w eat w // nope

Here, EatsOps[A <: Animal]可以先推断出什么A是,那么在eat[B <: Animal]它可以推断出什么B是,并使用有关两者的信息A and B插入正确的隐式。没有类型成员,扩展时无需执行任何操作Animal.

这有点像 XY 问题的 X 解决方案。是的,我重复使用了Animal代替Food...


Update

如果你想访问某个特定的私有方法Animal调用时执行eat,通常的方法是将所有基本功能移至Eats特征,然后提供实例Eats在特定的伴随对象中Animal。例如,我们可以这样让Cat做它不可思议的事private在真正吃之前的东西Bird:

trait Eats[A <: Animal, B <: Animal] {
  def apply(a: A, food: B): Unit
}

object Eats {
    def apply[A <: Animal, B <: Animal]: Eats[A, B] = new Eats[A, B] {
      def apply(animal: A, food: B) = println(s"${animal} eats ${food}")
    }
}

implicit class EatsOps[A <: Animal](animal: A) {
    def eat[B <: Animal](food: B)(implicit e: Eats[A, B]) = e(animal, food)
}

case class Cat() extends Animal {
  private def privateCatMethod(b: Bird): Unit = {}
}

object Cat {
  implicit val catsEatBirds: Eats[Cat, Bird] = new Eats[Cat, Bird] {
    def apply(c: Cat, b: Bird): Unit = {
      c.privateCatMethod(b)
      println(s"{c} eats {b}")
    }
  }
}

其余代码将保持不变,只是不需要e1: Eats[Cat, Bird]不再有。

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

使用动态/具体类型初始化类型变量 的相关文章

  • 如何在 scala repl 和 sbt 控制台中关闭/打开 typer 阶段

    是否可以在不退出当前会话的情况下切换阶段 我尝试进入 power 模式 但它仍然不打印类型 在SBT中只需添加以下设置 set scalacOptions in Compile console Xprint typer 在 REPL 中你可
  • 在 Spark 结构化流 2.3.0 中连接两个流时,左外连接不发出空值

    两个流上的左外连接不发出空输出 它只是等待记录添加到另一个流中 使用套接字流来测试这一点 在我们的例子中 我们想要发出具有 null 值的记录 这些记录与 id 不匹配或 且不属于时间范围条件 水印和间隔的详细信息如下 val ds1Map
  • 如何执行仅匹配正则表达式的测试?

    在 sbt 0 10 1 中 我经常使用test only缩小我的测试数量 sbt gt test only com example MySpec 但是 我想缩小范围 以便只运行名称 描述与正则表达式匹配的测试 是否有一些语法可以实现这样的
  • 如何使 PyCharm 从函数定义中获取类型提示并在文档字符串中填充类型值?

    我总是在函数定义中使用类型提示 例如 def foo a int b str gt bool pass 当我使用 PyCharm 自动文档字符串生成器在代码中生成文档字符串时 我得到以下信息 def foo a int b str gt b
  • 如何使用scala获取elasticsearch中_delete_by_query api的状态

    我正在 scala 中向 elasticsearch 发送 HTTP post Http s http elkIp 5051 indexName delete by query postData s query terms zip id k
  • Kafka 分区键无法正常工作

    我正在努力解决如何正确使用分区键机制的问题 我的逻辑是设置分区号为3 然后创建三个分区键为 0 1 2 然后使用分区键创建三个KeyedMessage 例如 KeyedMessage 主题 0 消息 KeyedMessage 主题 1 消息
  • 火花内存不足

    我有一个文件夹 里面有 150 G 的 txt 文件 大约 700 个文件 平均每个 200 MB 我使用 scala 来处理文件并最终计算一些汇总统计数据 我认为有两种可能的方法可以做到这一点 手动循环所有文件 对每个文件进行计算并最终合
  • Scala 的“神奇”函数列表

    在哪里可以找到 Scala 的 神奇 函数列表 例如apply unapply update etc 魔法函数是指编译器的某些语法糖使用的函数 例如 o update x y lt gt o x y 我用谷歌搜索了一些组合scala mag
  • 了解 Spark 中的 DAG

    问题是我有以下 DAG 我认为当需要洗牌时 火花将工作划分为不同的阶段 考虑阶段 0 和阶段 1 有些操作不需要洗牌 那么为什么 Spark 将它们分成不同的阶段呢 我认为跨分区的实际数据移动应该发生在第 2 阶段 因为这里我们需要cogr
  • 在 scala 宏中使用 LabelDef (2.10)

    我正在尝试 scala 2 10 宏功能 我使用时遇到问题LabelDef但在某些情况下 在某种程度上 我偷看了编译器的代码 阅读了摘录米格尔 加西亚的论文 http lampwww epfl ch magarcia但我还是卡住了 如果我的
  • 实现只有一个居民的类型的价值

    感谢 MilesSabin 的answer https stackoverflow com a 32157259 867671我可以编写类型级别的斐波那契序列 sealed trait Digit case object Zero exte
  • 用于共享大型不可变对象的工厂/缓存策略

    我的问题很像上一篇文章最佳哈希集初始化 Scala Java https stackoverflow com questions 14714900 optimal hashset initialization scala java 我想用的
  • 如何将 Dataframe 列名称与 Scala 案例类属性相匹配?

    本示例中的 Spark sql 列名来自case class Person case class Person name String age Int val people RDD Person An RDD of case class o
  • 将下划线分配给变量。下划线是做什么的?

    最近我遇到了这样的代码 var myVariable variableKind 这似乎是一种分配方式null to myVariable 谁能解释一下背后的理由 在这种情况下 分配之间有什么区别 and null到一个变量 它使用默认值初始
  • HDFS:使用 Java / Scala API 移动多个文件

    我需要使用 Java Scala 程序移动 HDFS 中对应于给定正则表达式的多个文件 例如 我必须移动所有名称为 xml从文件夹a到文件夹b 使用 shell 命令我可以使用以下命令 bin hdfs dfs mv a xml b 我可以
  • 使用什么框架来引导我的第一个生产 scala 项目?

    我正在第一次涉足 scala 的生产应用程序 该应用程序当前打包为 war 文件 我的计划是创建 scala 编译工件的 jar 文件 并将其添加到 war 文件的 lib 文件夹中 我的增强功能是通过 Jersey 公开的 mysql 支
  • python numpy:更改 numpy 矩阵的列类型

    我有一个 numpy 矩阵 X 我尝试使用以下代码更改第 1 列的数据类型 X 1 astype str print type X 0 1 但我得到了以下结果
  • Spark:导入UTF-8编码的文本文件

    我正在尝试处理一个包含很多特殊字符的文件 例如德语变音符号 o 等 如下所示 sc hadoopConfiguration set textinputformat record delimiter r n r n sc textFile f
  • 在 Scala 中提取案例类字段名称

    我有一个案例类 case class A field1 String field2 Int 我想在某些代码中引用确切的字符串 field1 例如 val q Query field1 gt hello performQuery q 现在我必
  • Spark-1.6.1 上的 DMLC 的 XGBoost-4j

    我正在尝试在 Spark 1 6 1 上使用 DMLC 的 XGBoost 实现 我能够使用 XGBoost 训练我的数据 但在预测方面面临困难 我实际上想以在 Apache Spark mllib 库中完成的方式进行预测 这有助于计算训练

随机推荐

  • 使用 matplotlib 和 seaborn 创建圆形密度图

    我正在尝试创建下面两个图像的组合 密度图 https i stack imgur com kV09a png 圆形条形图 https i stack imgur com tc7eG png 基本上我想要密度图的设计 但围绕一个圆圈而不是正常
  • Android:模拟器出厂数据重置菜单选项不起作用

    我正在尝试测试我自己创建的新 Android 系统级应用程序 该应用程序在执行设备出厂重置后捕获各种系统事件挂钩 通过 Android Studio AVD Manager 我创建了多个模拟 Android TV 设备 包括 Oreo 8
  • 数据框中每个唯一组合的频率

    在数据集中 N 6000 我想分析 15 个虚拟 变量组合出现的频率 ID Var1 Var2 Var3 Var15 1 1 0 0 1 2 0 1 1 1 3 1 0 0 0 6000 1 0 0 0 对于这个例子 我希望看到的是组合 1
  • 当使用字符串时,C++ 程序会出现运行时错误

    include
  • 如何运行 Visual Studio (2017) 安装程序?

    一旦你知道答案 它可能真的很明显 但我无法在任何地方找到它 我不是在谈论making安装程序 我指的是运行安装程序 让我可以修改安装的 Visual Studio 2017 的哪些功能 主屏幕如下所示 我需要的屏幕是这个 在 Visual
  • Javamail 附加多个文件

    以下代码也使用 javamail api 通过 gmail smtp 服务器发送邮件和附件 public void doSendGmail from txtFrom getText password new String txtPasswo
  • 如何运行后台进程并且不等待?

    我的目标很简单 启动 rsync 并且不要等待 Debian 上的 Python 2 7 9 示例代码 rsync cmd usr bin rsync a e ssh i home myuser ssh id rsa 0 1 2 3 for
  • java.io.IOException:准备失败。:状态= 0x1

    我在使用phonegap的媒体时得到这个 这首歌无法播放 而是收到错误代码 5 有任何想法吗 05 26 02 35 41 796 1153 8918 V PlayerDriver HandleInformationalEvent PVMF
  • 在 Windows 7 盒子(64 位)上从 vb.net 创建快捷方式

    我正在尝试在 Windows 7 机器 64 位 上从 vb net 代码创建桌面快捷方式 以下代码在 XP 上运行 但在 Win7 上运行时 我只收到一条消息 说明该应用程序已停止工作 Imports IWshRuntimeLibrary
  • 如何使用 Delphi Win32 编写 SOAP 1.2 客户端的最佳方式

    目前还没有Delphi版本支持SOAP http en wikipedia org wiki SOAP 28protocol 291 2 客户端或服务器 我已经尝试了几个星期让它工作 但每次出现新问题时 使用 VS C 我都可以做同样的事情
  • 用 JSX 中的标签替换部分字符串

    我正在尝试用 JSX 标签替换字符串的一部分 如下所示 render function result this props text replace div div return div result div 但考虑到this props
  • NestJs 中所有装饰器的 Eslint 错误“已定义但从未使用”警告

    我正在为一个项目使用 NestJs 框架 今天发现EsLint发现了587个错误的问题 所有装饰器都会生成此错误 warning IsBoolean is defined but never used typescript eslint n
  • 带通滤波器组

    我已经实现了一组定向带通滤波器本文中描述的 https www researchgate net publication 220539167 Multidirectional Scratch Detection and Restoratio
  • 是否可以自动获取 Intellij 的正则表达式帮助来获取自己的正则表达式参数

    Intellij 为需要正则表达式的参数提供正则表达式 帮助 语法检查 例如编码 String array string split 将在正则表达式下标记错误并提供工具提示错误 不封闭组 这也适用于变量 例如 String myVar sh
  • 使用 Pusher API 通知特定用户

    我有一个使用jquery mobile和phonegap的移动网络应用程序 另一个是php网站 我希望只向在线和移动应用程序上的特定用户发送通知 接收在php网站端和移动网络应用程序上在线的用户的通知所以我的问题是如何为特定用户设置频道 因
  • WPF BitmapFrame 和多线程

    我有一个 PNG 文件存储在我的云中的 blob 存储中 我想下载它并在 WPF 中将其渲染在屏幕上 我知道调度程序和冻结 但没有任何作用 我不断收到有关 另一个线程拥有它 的错误 这是我所拥有的 var decoder GetDecode
  • 如何为Python安装scipy?

    我有Python 2 7 而且我有迪斯图尔斯 http docs python org library distutils html安装 我下载了最新版本的Scipy 赢得 32 http sourceforge net projects
  • Ansible fileglob:无法在预期路径中找到...

    我正在尝试使用 ansible 删除目录中的所有文件 同时保留目录 为此 我正在使用with fileglob按任务键将所有文件从该目录中取出item变量 我创建了一个最小的示例来显示我的问题 流浪文件 Vagrant configure
  • 开发客户端-服务器 iPhone 应用程序

    如果我想开发一个采用客户端 服务器设计的 iPhone 应用程序 iPhone 设备作为客户端和 C 服务器 有两个问题 是否可以使用我自己的笔记本电脑来运行服务器 如果不是 我有什么选择 我是否必须开发自己的消息传输协议 因此 如果我理解
  • 使用动态/具体类型初始化类型变量

    我正在学习 Scala 我试图创建一个类型类来解决 每种动物都吃食物 但食物的类型取决于动物 的问题 我有一个Eats具有上下文边界的类型类 trait Eats A lt Animal B lt Edible object Eats de