回答:
単純なレコードは依存型のマップに対応します(まだマージ操作はありません)。より正確には、レコードタイプ
{ lbl1 : A1, lbl2 : A2, ..., lblN : AN }
製品タイプに対応
∏ (ℓ : label), A ℓ
label
合計タイプはどこですか
lbl1 + lbl2 + ... + lblN
でA : label → Type
定義されるタイプファミリーです
A lbl1 ≡ A1
A lbl2 ≡ A2
⋮
A lblN ≡ AN
上記のレコードタイプも単純な製品と同等です
A1 × A2 × ⋯ × AN.
拡張可能なレコードについて尋ねました。これを行うには、少なくとも2つの方法があります。追加のテクノロジーがなくても、
{ foo : A, bar : B } ≤ { foo : A, bar : B, baz C }
それらの間でマッピングする2つの関数を使用します(1つの方向への投影と、もう1つの方向での追加フィールドによる拡張)。これはすべて非常に平凡です。
すべての可能なレコードタイプのタイプを要求することもできます。label
考えられるすべてのラベルのタイプがあるとします(実際には、そのようなラベルがstring
いくつかあります)。タイプのすべてのレコードタイプがあります
record ≡ label → option Type
要素はR : record
、ラベルからオプションタイプへのマッピング、ある
R lbl
値をとるNone
ラベルがあればlbl
表示されないR
と値Some A
が表示された場合とタイプを持っていますA
。
場合はR : record
、その後でdecribedタイプはR
、製品の種類があります
∏ (ℓ : label),
match R ℓ with
| Some A ⇒ A
| None ⇒ unit
end
これはr
、タイプのレコードがR
依存関数であり、ラベルℓ
がA
ifの要素にℓ
出現しR
、それ以外の場合はユニットに出現することを意味します。
ただし、merge
操作には問題があり、サブタイプの関係もありR ≤ Q
ます。これは、ラベルlbl
がレコードR
とレコードで同じタイプであることを表現できないためQ
です。せいぜいあなたは型が同型であるか命題的に等しいと言うことができますが、それはあなたが望むものではありません。
私たちはできる定義extend
操作を
extend : record → record → record
ここで、最初の引数が 2番目の引数をオーバーライドするため、次extend R Q
のフィールドには表示されないフィールドがR
追加さQ
れR
ます。
extend R Q ≡
λ (ℓ : label),
match Q ℓ with
| Some A ⇒ Some A
| None ⇒ Q ℓ
end