scala - 检查无形中可扩展记录之间的子类型关系

标签 scala shapeless

我有两个无形的可扩展记录,personemployeeemployee 记录在某种意义上是 person 的子类型,因为它具有 person 的所有字段,并且这些字段都是 person 的子类型person中的相应字段:

import shapeless._ ; import syntax.singleton._ ; import record._

val employeeId = ("first name" ->> "Jane") :: ("last name" ->> "Doe") :: ("title" ->> "software engineer") :: HNil

val employee =
      ("id" ->> employeeId) ::
      ("city" ->> "San Francisco") ::
      ("company" ->> "Generic Inc.") ::
      HNil

val personId = ("first name" ->> "Jane") :: ("last name" ->> "Doe") :: HNil

val person =
      ("id" ->> personId) ::
      ("city" ->> "San Francisco") ::
      HNil

如何检查一条记录是否是另一条记录的子类型?我希望能够在编译时和运行时都执行此操作。我想到的一个用例是我想静态验证一个函数不会从记录中删除任何字段。所以我的函数可以接受一个 person 并将其转换为 employee 但如果它删除了“city”或“id”字段,程序将无法编译。

我还希望能够比较employeeperson 的共享组件。我想将这两个对象都视为 person 并检查它们是否相等。我该怎么做?

最佳答案

  • 如何检查一条记录是否是另一条记录的子类型?

您可以查看此存储库中的 Extractor 类型类。它实现了深度和宽度子类型化。

https://github.com/eugengarkusha/RecordsDeepMerge

  • 我希望能够在编译时和运行时执行此操作

在编译时见证了子类型关系。 使用 Extractor 类型类(来自提到的 repo)从子记录中获取 super 记录的所有字段。

  • 我还希望能够比较 employee 和 person 的共享组件。我想将两个对象都视为人,并检查它们是否相等。我该怎么做?

(使用上述代码库中的代码):

 type PersonId = Record.`"first name" ->String, "last name" ->String`.T
 type Person = Record.`"id" -> PersonId, "city" -> String`.T 
 employee1.deepExtract[Person] == employee2.deepExtract[Person]
  • 我想静态验证函数不会从记录中删除任何字段。所以我的函数可以接受一个人并将其转换为一名雇员,但如果它删除了“城市”或“id”字段,则程序不应编译。

在这种情况下不需要子类型检查:

def personToEmployee(p: Person): Employee = ???

类型检查器不会让您删除城市或 ID 字段

关于scala - 检查无形中可扩展记录之间的子类型关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32803930/

相关文章:

scala - 什么时候需要 Scala 分号

scala - 如何使用属性和类型类无形的案例类?

scala - 有没有办法使用对象的类型作为类型参数的参数?

scala - 给定一个 HList 你如何得到一个 HMap

scala - 用于无形状可扩展记录的 API

scala - PlayFramework 测试 : Uploading File in Fake Request Errors

scala - 2.7.7下编译AKKA代码时出错

scala - gradle 中的影子插件无法正常工作 - gradle build 不会构建 fat jar

scala - 用于理解 scala 中的列表/集合

scala - Shapeless的“惰性”和默认参数导致隐式解析失败