【问题标题】:Checking for subtype relationship between extensible records in shapeless检查无形中可扩展记录之间的子类型关系
【发布时间】:2017-05-02 06:00:13
【问题描述】:

我有两个无形可扩展记录,personemployeeemployee 记录在某种意义上是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 的共享组件。我想将这两个对象都视为persons 并检查它们是否相等。我该怎么做?

【问题讨论】:

    标签: scala shapeless


    【解决方案1】:
    • 如何检查一个记录是否是另一个记录的子类型?

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

    https://github.com/eugengarkusha/RecordsDeepMerge

    • 我希望能够在编译时和运行时都这样做

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

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

    (使用提到的 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”字段,则程序不应编译。

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

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

    类型检查器不允许您删除城市或 ID 字段

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多