2015-09-27 33 views
3

我有兩個無形的可擴展記錄,personemployee。該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,但如果它刪除「城市」或「ID」字段,程序不應該編譯。

我也希望能夠比較employeeperson的共享組件。我想查看這兩個對象只是person s並檢查它們是否相等。我怎樣才能做到這一點?

回答

1
  • 如何檢查一條記錄是否是另一條記錄的子類型?

您可以查看此回購協議中的提取器類型類。它實現深度和寬度子類型。

https://github.com/eugengarkusha/RecordsDeepMerge

  • 我希望能夠既在編譯時和運行時

分型關係在編譯的時候親眼目睹做到這一點。 使用提取器類型類(從提到的回購)從子記錄獲取超級記錄的所有字段。

  • 我還希望能夠比較員工和個人的共享組件。我想查看這兩個對象只是個人,並檢查它們是否相等。我怎樣才能做到這一點?

(使用提及回購的代碼):

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字段

+0

此功能將存在於無形的2.3.3 HTTPS ://github.com/milessabin/shapeless/pull/714 –