问题描述
我有两个无形的可扩展记录,person
和 employee
.employee
记录在某种意义上是 person
的子类型,因为它具有 person
所做的所有字段,并且这些字段都是person
中对应的字段:
I have two shapeless extensible records, person
and employee
. The employee
record is a subtype of person
in some sense because it has all of the fields that person
does and those fields are all subtypes of the corresponding fields in 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"字段,程序就不应该编译.
How can I check if one record is a subtype of another? I want to be able to do this both at compile time and at runtime. One use-case I have in mind is that I want to statically verify that a function doesn't remove any fields from a record. So my function could take a person
and transform it into an employee
but if it dropped the "city" or "id" fields the program should not compile.
我还希望能够比较 employee
和 person
的共享组件.我想将两个对象都视为 person
并检查它们是否相等.我该怎么做?
I also want to be able to compare the shared components of employee
and person
. I want to view both objects as just person
s and check them for equality. How can I do this?
推荐答案
- 如何检查一个记录是否是另一个记录的子类型?
- 我希望能够在编译时和运行时执行此操作
- 我还希望能够比较员工和人员的共享组成部分.我想将两个对象都视为人并检查它们是否相等.我该怎么做?
您可以查看此 repo 中的 Extractor 类型类.它实现了深度和宽度子类型.
You may look at the Extractor type class in this repo. It implements both depth and width subtyping.
https://github.com/eugengarkusha/RecordsDeepMerge
子类型关系在编译时可见.使用 Extractor 类型类(来自提到的 repo)从子记录中获取超级记录的所有字段.
Subtyping relation is witnessed in compile time.Use the Extractor type class(from mentioned repo) to get all fields of super-record from sub-record.
(使用来自上述 repo 的代码):
(using the code from mentioned repo):
type PersonId = Record.`"first name" ->String, "last name" ->String`.T
type Person = Record.`"id" -> PersonId, "city" -> String`.T
employee1.deepExtract[Person] == employee2.deepExtract[Person]
- 我想静态验证函数不会从记录中删除任何字段.所以我的函数可以接受一个人并将其转换为员工,但如果它删除了city"或id"字段,程序就不应编译.
在这种情况下不需要子类型检查:
no subtype checks are needed in this case:
def personToEmployee(p: Person): Employee = ???
类型检查器不会让您删除城市或 ID 字段
type checker won't let you remove city or id fields
这篇关于检查无形中可扩展记录之间的子类型关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!