Saya bereksperimen dengan sistem tipe murni dalam kubus lambda Barendregt, khususnya dengan yang paling kuat, Kalkulus Konstruksi. Sistem ini memiliki macam *
dan BOX
. Sebagai catatan, di bawah ini saya menggunakan sintaks konkret dari Morte
alat https://github.com/Gabriel439/Haskell-Morte-Library yang dekat dengan kalkulus lambda klasik.
Saya melihat kita dapat meniru tipe induktif dengan semacam pengkodean seperti Gereja (alias isomorfisma Boehm-Berarducci untuk tipe data aljabar). Sebagai contoh sederhana saya menggunakan tipe Bool = ∀(t : *) -> t -> t -> t
dengan konstruktor True = λ(t : *) -> λ(x : t) -> λ(y : t) -> x
dan False = λ(t : *) -> λ(x : t) -> λ(y : t) -> y
.
Saya melihat bahwa tipe fungsi level-level Bool -> T
adalah isomorfik untuk pasangan tipe Product T T
dengan Product = λ(A : *) -> λ(B : *) -> ∀(t : *) -> (A -> B -> t) -> t
parametrik modulo klasik dengan fungsi if : Bool -> λ(t : *) -> t -> t -> t
yang sebenarnya merupakan identitas.
Semua pertanyaan di bawah ini adalah tentang representasi tipe dependen Bool -> *
.
Saya dapat dibagi
D : Bool -> *
menjadi sepasangD True
danD False
. Apakah ada cara kanonik untuk menciptakanD
lagi? Saya ingin mereproduksi isomosismeBool -> T = Product T T
dengan analog fungsiif
pada level type tetapi saya tidak dapat menulis fungsi ini sesederhana aslinyaif
karena kita tidak dapat melewatkan jenis dalam argumen seperti tipe.Saya menggunakan jenis tipe induktif dengan dua konstruktor untuk menyelesaikan pertanyaan (1). Deskripsi tingkat tinggi (Agda-style) adalah tipe berikut (digunakan sebagai ganti tipe-level
if
)data BoolDep (T : *) (F : *) : Bool -> * where DepTrue : T -> BoolDep T F True DepFalse : F -> BoolDep T F False
dengan penyandian berikut di PTS / CoC:
λ(T : *) -> λ(F : *) -> λ(bool : Bool ) -> ∀(P : Bool -> *) -> ∀(DepTrue : T -> P True ) -> ∀(DepFalse : F -> P False ) -> P bool
Apakah pengkodean saya di atas benar?
Saya dapat menuliskan konstruktor untuk
BoolDep
seperti kode ini untukDepTrue : ∀(T : *) -> ∀(F : *) -> T -> BoolDep T F True
:λ(T : *) -> λ(F : *) -> λ(arg : T ) -> λ(P : Bool -> *) -> λ(DepTrue : T -> P True ) -> λ(DepFalse : F -> P False ) -> DepTrue arg
tapi saya tidak bisa menuliskan fungsi terbalik (atau fungsi apa pun di arah terbalik). Apa itu mungkin? Atau haruskah saya menggunakan representasi lain untuk BoolDep
menghasilkan isomorfisme BoolDep T F True = T
?