具有 ADT 和 Aux 模式的类型安全

2024-03-09

我正在使用 ADT 和 Aux 模式设计类型安全代码,并且无法摆脱一些asInstanceOf。这是示例:

  sealed trait Source
  case object FileSystem extends Source
  case object Network extends Source

  sealed trait Data {
    type S <: Source
  }
  object Data {
    type Aux[T <: Source] = Data { type S = T }
  }
  case class RegularFile(path: String) extends Data { type S = FileSystem.type }
  case class Directory(path: String) extends Data { type S = FileSystem.type }
  case class UnixDevice(path: String) extends Data { type S = FileSystem.type }
  case class Remote(ip: String) extends Data { type S = Network.type }

  //Lots of asInstanceOf
  def availableData[S <: Source](src: Source): List[Data.Aux[S]] = {
    src match {
      case FileSystem => List(
        RegularFile("/tmp/test").asInstanceOf[Data.Aux[S]],
        Directory("/home/somename").asInstanceOf[Data.Aux[S]],
        UnixDevice("/dev/null").asInstanceOf[Data.Aux[S]],
      )
      case Network => List(
        Remote("192.168.0.1").asInstanceOf[Data.Aux[S]]
      )
    }
  }

在这种情况下,很明显asInstanceOf是正确的,但是有没有办法摆脱它呢?

我正在考虑S <: Source: ClassTag,不过这里好像没什么用。也许还有其他反射技巧?


请参阅解释为什么签名

def availableData[S <: Source](src: S): List[Data.Aux[S]] = {
  src match {
    case FileSystem => List(
      RegularFile("/tmp/test"),
      Directory("/home/somename"),
      UnixDevice("/dev/null"),
    )
    case Network => List(
      Remote("192.168.0.1")
    )
  }
}

不起作用,有几种修复方法:

Scala 中返回类型取决于输入类型的通用函数? https://stackoverflow.com/questions/64318180/generic-function-where-the-return-type-depends-on-the-input-type-in-scala

如果将 A 的泛型子类型声明为返回参数,为什么我不能返回 A 的具体子类型? https://stackoverflow.com/questions/61668592/why-cant-i-return-a-concrete-subtype-of-a-if-a-generic-subtype-of-a-is-declared/

模式匹配中使用的抽象类型的类型不匹配 https://stackoverflow.com/questions/52479695/type-mismatch-on-abstract-type-used-in-pattern-matching

例如尝试一个类型类

trait AvailableData[S <: Source] {
  def availableData(src: S): List[Data.Aux[S]]
}
object AvailableData {
  implicit val fileSystem: AvailableData[FileSystem.type] = _ =>
    List[Data.Aux[FileSystem.type]](
      RegularFile("/tmp/test"),
      Directory("/home/somename"),
      UnixDevice("/dev/null"),
    )
  implicit val network: AvailableData[Network.type] = _ =>
    List[Data.Aux[Network.type]](
      Remote("192.168.0.1")
    )
}

def availableData[S <: Source](src: S)(implicit 
  ad: AvailableData[S]
): List[Data.Aux[S]] = ad.availableData(src)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有 ADT 和 Aux 模式的类型安全 的相关文章

随机推荐

  • 与 char *、unsigned char * 和signed char * 别名

    A char 和合格的变体 可以为任何东西起别名 是signed char and unsigned char 及其合格的变体 不受此限制 换句话说 我了解到申请是个好主意restrict to char 函数参数 如果我不希望它们为其他类
  • GWT - 构造 Java AST 时出错

    编译过程中可能是什么原因导致此错误 我已经从这个原型生成了项目https github com ArcBees Arcbees Archetypes https github com ArcBees Arcbees Archetypes我只
  • OpenGL ES 和 OpenGL 兼容着色器

    我想要 OpenGL ES 和 OpenGL Windows 具有相同的着色器源 为此 我想定义自定义数据类型并仅使用 OpenGL ES 函数 一种方法是定义 define highp define mediump define lowp
  • JavaFX 8 计算“textarea”中的行数

    我们正在尝试计算 TextArea 中的行数以下是 TextArea 属性 PrefWidth 600 和 PrefHeight 620 以及 MaxHeight 620文本换行设置为 true 我们将 JavaFX 8 与场景生成器一起使
  • 小时显示 hourSegments 角度日历

    在我的日历中 我需要显示一天和一周的时间 如下所示 09 00 09 15 09 20 我把包升级到最新了 angular calendar version 0 26 1 现在下面的代码出现错误 我无法再像以前一样显示时间 模块 ts cl
  • 复制并粘贴值而不是公式

    第一次编写宏 我必须仅将单元格值复制到另一个单元格值 并且我让它工作 但是 我不确定如何在不指定范围的情况下复制整个列 因为范围每次可能不同 在这里 我尝试使用一个有效的范围 但我希望它检查该列的单元格值 直到找到值复制 粘贴到另一列 这是
  • Vue.js / webpack 没有创建构建文件?

    这可能是一个愚蠢的问题 但到底是什么 我正在使用 vue cliwebpack simple模板 在该项目的 webpack 配置中我发现以下内容 output path path resolve dirname dist publicPa
  • 使“枚举时修改”集合成为线程安全的

    我想创建一个线程安全的集合 可以在枚举时进行修改 例子ActionSet类商店Action处理程序 它有Add方法将新的处理程序添加到列表中 并且Invoke枚举并调用所有收集的操作处理程序的方法 预期的工作场景包括非常频繁的枚举 并且在枚
  • Java dom4j org/jaxen/NamespaceContext 异常

    我已经下载了并将其添加到java的构建路径中 我也熟悉java lang NoClassDefFoundError org saxpath SAXPathException https stackoverflow com questions
  • 程序如何覆盖之前的输出行?

    程序如vim top or alsamixer输出多行文本并以某种方式操作已写入的文本行 我知道写 r字符到 stdout 这会将光标返回到行的开头 允许覆盖当前行 但不能覆盖之前的任何行 这些程序正在做什么才能拥有这些更高级的用户界面以及
  • 如何通过 DialogFragment 使用 startActivityForResult() ?

    我的应用程序需要添加用户名才能正常运行 mainActivity 在顶部显示从数据库检索的用户名 mainActivity 还有一个按钮 可通过 startActivityForResult 方法进入 addusername 活动 当用户实
  • Composer 缓存不适用于 bitbucket 管道构建

    我在我的 bitbucket 管道中得到了这个 pipelines branches develop step caches composer name unit tests Delivery image totersapp laravel
  • 为什么委托中所有方法都具有相同的名称?

    我从 Swift 开始 开发一个带有 tableView 的简单应用程序 对服务器的请求以及其他一些内容 我意识到 UITableViewDelegate 协议中的每个方法都以相同的方式命名 我猜它可能与其他协议相同 并且通过更改传递给这些
  • GCC 是否优化汇编源文件?

    我可以使用 GCC 将汇编代码文件转换为可重新分配的文件 gcc c source S o object o O2 优化选项是否有效 我可以期望 GCC 优化我的汇编代码吗 No GCC 将汇编源代码通过预处理器 然后传递到汇编器 任何时候
  • Java泛型通配符问题

    在使用 Google Guava 优秀的 Multimap 时 我遇到了一些泛型问题 我有一个这样定义的类型处理程序 public interface Handler
  • 从 ASP.net MVC 3 项目中删除默认 JavaScript 文件

    我刚刚开始使用 ASP net MVC 3 并且创建了一个空项目 我注意到脚本文件夹中填充了许多 JavaScript 文件 包括 jQuery 1 5 1 jQuery 用户界面 1 8 11 一些 jQuery 插件 ASP net M
  • 如何在Python中检查它是否是存档的文件或文件夹?

    我有一个存档 我不想提取它 但检查它的每个内容 无论它是文件还是目录 os path isdir 和 os path isfile 不起作用 因为我正在处理存档 存档可以是 tar bz2 zip 或 tar gz 中的任何一个 所以我不能
  • 捕获未通过 QuickFix 验证的传入 FIX 消息

    A Quickfix http www quickfixengine org 客户端使用以下方法验证传入消息XML 规范文件 http www quickfixengine org documentation 如果消息验证失败 quickf
  • 将数据从 UITableViewCell 推送到 UINavigationController

    我有一个 UISearchDisplaycontroller 我必须将信息推送到文本字段 并需要将其链接到导航视图控制器 这是我的代码 void prepareForSegue UIStoryboardSegue segue sender
  • 具有 ADT 和 Aux 模式的类型安全

    我正在使用 ADT 和 Aux 模式设计类型安全代码 并且无法摆脱一些asInstanceOf 这是示例 sealed trait Source case object FileSystem extends Source case obje