我有两个无形的可扩展记录person
和employee
。 employee
记录在某种意义上是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”字段,程序就不应该编译。
我还希望能够比较employee
和person
的共享组件。我想将这两个对象视为person
,并检查它们是否相等。我怎么能这样做?
答案 0 :(得分:1)
您可以查看此仓库中的Extractor类型类。它实现了深度和宽度子类型。
https://github.com/eugengarkusha/RecordsDeepMerge
在编译时见证了子类型关系。 使用Extractor类型类(来自提到的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]
在这种情况下不需要进行子类型检查:
def personToEmployee(p: Person): Employee = ???
类型检查器不允许您删除城市或ID字段