Scala:通过依赖注入协调类型类

2024-02-06

最近,Scala 博主们似乎对类型类模式,其中一个简单的类具有由符合某些特征或模式的附加类添加的功能。作为一个过于简单化的例子,简单的类:

case class Wotsit (value: Int)

可以适应 Foo 特征:

trait Foo[T] {
  def write (t: T): Unit
}

在此类的帮助下:

implicit object WotsitIsFoo extends Foo[Wotsit] {
  def write (wotsit: Wotsit) = println(wotsit.value)
}

类型类通常在编译时通过隐式捕获,允许将 Wotsit 及其类型类一起传递到高阶函数中:

def writeAll[T] (items: List[T])(implicit tc: Foo[T]) =
  items.foreach(w => tc.write(w))

writeAll(wotsits)

(在你纠正我之前,我说过这是一个过于简单的例子)

However,隐式的使用假定在编译时已知项的精确类型。我发现在我的代码中通常情况并非如此:我将拥有某种类型的项目 List[T] 的列表,并且需要发现正确的类型类来处理它们。

Scala 建议的方法似乎是在调用层次结构中的所有点添加 typeclass 参数。当代码扩展时,这可能会变得烦人,并且这些依赖项需要通过它们越来越不相关的方法沿着越来越长的链传递。这使得代码变得混乱且难以维护,这与 Scala 的初衷相反。

通常,这是依赖注入介入的地方,使用库在需要时提供所需的对象。详细信息因为 DI 选择的库而异 - 我过去用 Java 编写了自己的库 - 但通常注入点需要精确定义所需的对象。

问题是,对于类型类,精确值在编译时是未知的。必须根据多态性描述来选择它。至关重要的是,类型信息已被编译器删除。清单是 Scala 的类型擦除解决方案,但我还不清楚如何使用它们来解决这个问题。

人们会建议使用哪些 Scala 技术和依赖注入库来解决这个问题?我错过了一个技巧吗?完美的 DI 库?或者这确实是症结所在?


澄清

我认为这实际上有两个方面。在第一种情况下,需要类型类的点是通过从已知其操作数的确切类型的点进行直接函数调用来到达的,因此足够的类型争论和语法糖可以允许将类型类传递给点它是需要的。

在第二种情况下,这两点被屏障分开 - 例如无法更改的 API,或存储在数据库或对象存储中,或序列化并发送到另一台计算机 - 这意味着类型类可以' t 与其操作数一起传递。在这种情况下,给定一个其类型和值仅在运行时已知的对象,需要以某种方式发现类型类。

我认为函数式程序员习惯于假设第一种情况——使用足够高级的语言,操作数的类型总是可知的。 David 和 mkniessl 对此提供了很好的答案,我当然不想批评这些。但第二种情况确实存在,这就是为什么我将依赖注入引入到问题中。


通过使用新的上下文绑定语法,可以减轻传递这些隐式依赖项的大量繁琐工作。你的例子变成

def writeAll[T:Foo] (items: List[T]) =
  items.foreach(w => implicitly[Foo[T]].write(w))

它的编译方式相同,但可以产生漂亮而清晰的签名,并且周围有更少的“噪音”变量。

这不是一个很好的答案,但替代方案可能涉及反射,而且我不知道有任何库可以使其自动工作。

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

Scala:通过依赖注入协调类型类 的相关文章

  • 如何从DataFrame中获取最后一行?

    我有一个DataFrame 该DataFrame有两列 value 和 timestamp timestmp 是有序的 我想获取DataFrame的最后一行 我该怎么办 这是我的输入 value timestamp 1 1 4 2 3 3
  • Akka Stream - 根据 Flow 中的元素选择 Sink

    我正在使用 Akka 流创建一个简单的消息传递服务 该服务就像邮件递送一样 其中来自源的元素包括destination and content like case class Message destination String conte
  • 如何通过数据框中数组列的索引计算平均值

    我正在使用 Spark 2 2 我有一个关于合作的基本问题ArrayType 我没有找到可以使用的内置聚合函数 Given a DataFrame有一个柱子id和一列values of ArrayType 我们想按 id 分组 然后按索引计
  • 如何在单独的文件中使用 FastAPI Depends 作为端点/路由?

    我在单独的文件中定义了一个 Websocket 端点 例如 from starlette endpoints import WebSocketEndpoint from connection service import Connectio
  • 如何最好地处理 Future.filter 谓词不满足类型错误

    我喜欢 scala 的类型安全性 但我不断遇到的一个运行时错误是 Future filter predicate is not satisfied 我知道为什么会出现此错误 只是寻求有关如何最好地解决此错误并优雅地处理它的建议 或者也许我做
  • 标识符中下划线的 Scala 风格指南

    我已经接受了许多其他语言的观点 即下划线在标识符中具有与字母表一样多的自由度 因此 v and v 另外 尾随下划线是受到推崇的避免与保留关键字产生歧义 class case val abc 0
  • 注入需要构造函数参数的服务

    我有一项服务需要启动一些值 Injectable export class MyService private myVals any constructor init any this myVals init 而消费者 Component
  • 什么时候有2.13的sbt版本?

    我想开发一个sbt插件其依赖项仅适用于斯卡拉2 13 我发现https github com sbt sbt issues 5032 https github com sbt sbt issues 5032这个列表 SBT 0 x 仅在 S
  • 如何处理 Spark 数据框中外连接的数据倾斜

    我有两个数据框 正在对 5 列执行外连接 下面是我的数据集的示例 uniqueFundamentalSet PeriodId SourceId StatementTypeCode StatementCurrencyId FinancialS
  • Symfony - 自定义验证器和依赖注入

    我正在尝试对自定义验证器使用依赖项注入 以便能够使用实体管理器 我遵循 Symfony 示例 依赖注入 http symfony com doc current cookbook validation custom constraint h
  • scalac 编译生成“对象 apache 不是包 org 的成员”

    我的代码是 import org apache spark SparkContext 它可以在交互模式下运行 但是当我使用 scalac 编译它时 出现以下错误消息 对象 apache 不是包 org 的成员 这似乎是路径的问题 但我不知道
  • 在 Scala 中实现不区分大小写比较的字符串类

    我有许多带有不区分大小写的字段的类 我想将这些类的实例放入 HashMap 中 并通过不区分大小写的字符串查找它们 我不是每次想通过字符串索引实例或通过字符串查找实例时都使用 toLowerCase 而是尝试将此逻辑封装在 CaseInse
  • 视图和流有什么区别?

    在Scala 2 8集合框架中 有什么区别view and toStream 在视图中 每次访问元素时都会重新计算它们 在流中 元素在求值时会被保留 例如 val doubled List 1 2 3 4 5 6 7 8 9 10 view
  • 如何对 RDD 进行分区

    我有一个文本文件 其中包含大量由空格分隔的随机浮动值 我正在将此文件加载到 scala 中的 RDD 中 这个RDD是如何分区的 另外 是否有任何方法可以生成自定义分区 以便所有分区都具有相同数量的元素以及每个分区的索引 val dRDD
  • 在 scalaz 中免费实施

    Haskell 中的免费实现是 data Free f a Pure a Free f Free f a 而 Scalaz 中的实现是 sealed abstract class Free S A private case class Re
  • 隐式类中的 Scala 按名称调用构造函数参数

    下面的代码不编译 期望的是在隐式类中有一个按名称调用构造函数参数 如下所示 def f n Int 1 to n product implicit class RichElapsed A val f gt A extends AnyVal
  • 为什么这个 Clojure 程序在可变数组上运行如此慢?

    剧透警告 这是 代码降临 第六天的第一部分 我试图解决this http adventofcode com day 6Clojure 和 Scala 中的问题 Scala 程序在我的 Macbook Air 上运行良好 几秒钟内就完成了 然
  • Scala 宏 - 使用“c.prefix”推断隐式值

    c inferImplicitValue推断调用站点范围中的隐式值 是否可以使用推断隐式c prefix scope 这不是有效的代码 但表达了我需要的内容 c prefix inferImplicitValue 我目前正在使用一个简单的实
  • 注入包含接口的所有已注册实现的 Enumerable

    给出以下接口 public interface IMyProcessor void Process 我希望能够注册多个实现 并让我的 DI 容器将它们的可枚举注入到这样的类中 public class MyProcessorLibrary
  • 应用服务器如何注入私有字段?

    我看到这个问题 注入私有 包或公共字段或提供 setter https stackoverflow com questions 2021716 inject into private package or public field or p

随机推荐

  • .NET Windows 窗体应用程序是否可以在 64 位操作系统中运行,或者是否需要修改?

    一般来说 NET Windows 窗体应用程序可以在 64 位操作系统中运行吗 还是需要修改 如果它不依赖于 32 位外部库 例如 COM 组件 它将作为 64 位进程完美工作 并利用其优势 大地址空间 x64 指令集 如果它依赖于 32
  • xaml.cs 中的 Xamarin 局部变量并通过 XAML 文件进行打印

    我希望能够打印 XAML 中 CurrentOrder 的属性 这是我到目前为止所拥有的 OrderPage xaml cs public partial class OrderPage ContentPage private Order
  • 使用 MediatR 时可以让一个处理程序调用另一个处理程序吗?

    或者这被认为是不好的做法还是什么 我有一个通知触发 4 5 个处理程序 这些处理程序依次调用数据库来检索数据 每个这些调用也可以单独调用 因此它们本身就是请求 处理程序 Thanks Jimmy Bogard mediatr 的作者 说你应
  • CListCtrl 用鼠标选择多行

    There is a CListCtrl with SetExtendedStyle LVS EX GRIDLINES LVS EX FULLROWSELECT a single selection is false I want to b
  • 如何使用Windows Media Player播放加密的视频文件?

    我加密我的 mp4转换为自定义格式 opu 现在我应该解密我的文件并将它们保存到应用程序开始时的临时文件夹中 并使用它们来播放WindowsMediaPlayerC 中的控制 所以我有从临时文件夹中窃取文件的风险 防止我的文件被盗的最佳方法
  • 从亚马逊s3存储桶检索静态文件

    我正在尝试以这样的方式配置我的 nginx 每当出现一些错误的网关响应时 我都会尝试从 s3 存储桶中获取静态 html 内容 请求的url结构为some bucket folder1 folder2 text 数据存储在 s3 存储桶中
  • 如何设置编辑器以在 Windows 上使用 Git?

    我正在尝试Windows 上的 Git 我尝试 git commit 并收到此错误 终端很笨 但没有 VISUAL 也没有 编辑器定义 请提供 使用 m 或 F 选项的消息 所以我发现我需要一个名为 EDITOR 的环境变量 没问题 我将其
  • 单元测试 Maven 插件

    我正在寻找有关如何为 Maven 插件编写单元测试的信息 虽然有a page http maven apache org plugin developers plugin testing html在关于这一主题的 Maven 站点上 只有一
  • 不可哈希类型:“dict”类型错误[重复]

    这个问题在这里已经有答案了 假设我有这本字典 items 1 title u testing123 description u testing456 2 description u testing123 description u test
  • IPython 中的物理括号符号

    我正在努力拥有ket符号通常在乳胶中写为 ket psi 然而 当写在 当使用以下方式编写时 这也不起作用IPython display latex documentclass article usepackage amsmath begi
  • AngularJS - 将多个 get 请求收集到 json 数组中,然后传递给指令

    我是角度新手 一直在努力解决我的问题 我需要多次访问 API 来获取用户数据 将所有内容存储为 JSON 数组 当收集所有数据 所有结果作为一个数组 时 需要将其传递给指令 该指令将使用它来绘制可视化 例如 d3 js 饼形图 scope
  • ctx.Err() 与 ctx.Done() chan 关闭检查:有区别吗?

    我处于一个长时间运行的可取消函数中 该函数具有永远循环 我需要检查上下文是否已关闭 go func for if ctx Err nil return do work vs go func for select case lt ctx Do
  • Xcode 组织者尝试在错误的目录路径访问传输程序

    Transporter not found at path usr local itms bin iTMSTransporter You should reinstall the application 所以我检查了路径 Applicati
  • java 具有透明度的全屏窗口

    我正在尝试使用 Java 创建一个覆盖整个屏幕的全屏窗口 这个窗口还必须有一定的透明度 大约30 50 透明 当我说整个屏幕时 我的意思是它覆盖了所有内容 包括 OSX Linux Windows 中的扩展坞 任务栏 菜单栏 当我说透明度时
  • Autofac - 将属性注入 asp.net mvc 控制器

    我有一个基本控制器 它继承了我的所有控制器 这个基本控制器有一些属性 我想使用属性注入来注入 我的控制器注册看起来像这样 builder RegisterControllers Assembly GetExecutingAssembly 我
  • 在 ListView 布局模板中显示总计

    我使用 ListView 控件 ASP NET 2008 来显示一堆数据行 在底部我想要一些总计 我最初打算在 LayoutTemplate 中定义页眉和页脚 并使用一些本地函数 即 获取总计 但 LayoutTemplate 似乎不处理
  • 如何使用 java Firebase Admin SDK 将分析标签添加到数据消息?

    自 7 月 1 日起 Firebase 要求向消息添加标签 以便分析显示数据消息发送的数量等 从 2019 年 7 月 1 日星期一开始 您将能够通过分析标签过滤数据 在该日期之后 没有分析标签发送的数据消息可能不会在此仪表板中显示 问题是
  • 连续检查队列

    我想要一个函数来在一个线程上连续检查队列是否有新添加 显然 可以选择连续循环睡眠 但我想要一些不那么浪费的东西 我考虑了某种类型的等待句柄 然后让队列向它发出信号 但我无法安全地覆盖 Enqueue 因为它不是虚拟的 现在我正在考虑封装一个
  • 奇怪的重复出现的模板和模板参数相关的子类化问题

    我正在尝试使以下代码工作 template lt class derived class object typename derived Object gt struct Base using Derived derived using O
  • Scala:通过依赖注入协调类型类

    最近 Scala 博主们似乎对类型类模式 其中一个简单的类具有由符合某些特征或模式的附加类添加的功能 作为一个过于简单化的例子 简单的类 case class Wotsit value Int 可以适应 Foo 特征 trait Foo T