检查无形中可扩展记录之间的子类型关系 [英] Checking for subtype relationship between extensible records in shapeless

查看:40
本文介绍了检查无形中可扩展记录之间的子类型关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个无形的可扩展记录,personemployee.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.

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

I also want to be able to compare the shared components of employee and person. I want to view both objects as just persons 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

      这篇关于检查无形中可扩展记录之间的子类型关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆