Eksperymentuję z systemami czystego typu w sześcianie lambda Barendregta, a konkretnie z najsilniejszym z nich, Rachunkiem Konstrukcji. Ten system ma rodzaje *i BOX. Dla przypomnienia, poniżej używam konkretnej składni Mortenarzędzia https://github.com/Gabriel439/Haskell-Morte-Library, która jest zbliżona do klasycznego rachunku lambda.
Widzę, że możemy emulować typy indukcyjne za pomocą pewnego rodzaju kodowania podobnego do Kościoła (znanego również jako izomorfizm Boehm-Berarducci dla algebraicznych typów danych). Dla prostego przykładu używam typu Bool = ∀(t : *) -> t -> t -> tz konstruktorami True = λ(t : *) -> λ(x : t) -> λ(y : t) -> xi False = λ(t : *) -> λ(x : t) -> λ(y : t) -> y.
Widzę, że typ funkcji na poziomie terminu Bool -> Tjest izomorficzny w stosunku do par typu Product T To klasycznej Product = λ(A : *) -> λ(B : *) -> ∀(t : *) -> (A -> B -> t) -> tparametryczności modularnej za pomocą funkcji, if : Bool -> λ(t : *) -> t -> t -> tktóra w rzeczywistości jest identyczna.
Wszystkie poniższe pytania dotyczą reprezentacji typów zależnych Bool -> *.
Mogę podzielić
D : Bool -> *na paręD TrueiD False. Czy istnieje kanoniczny sposób naDponowne utworzenie ? Chcę odtworzyć izomoszmizmBool -> T = Product T Tprzez analog funkcjiifna poziomie typu, ale nie mogę napisać tej funkcji tak prostej jak oryginał,ifponieważ nie możemy przekazywać rodzajów w argumentach takich jak typy.Używam rodzaju indukcyjnego z dwoma konstruktorami do rozwiązania pytania (1). Opis wysokiego poziomu (w stylu Agda) to następujący typ (używany zamiast poziomu
if)data BoolDep (T : *) (F : *) : Bool -> * where DepTrue : T -> BoolDep T F True DepFalse : F -> BoolDep T F Falsez następującym kodowaniem w PTS / CoC:
λ(T : *) -> λ(F : *) -> λ(bool : Bool ) -> ∀(P : Bool -> *) -> ∀(DepTrue : T -> P True ) -> ∀(DepFalse : F -> P False ) -> P boolCzy moje kodowanie powyżej jest prawidłowe?
Mogę zapisać konstruktory dla
BoolDeptakiego kodu dlaDepTrue : ∀(T : *) -> ∀(F : *) -> T -> BoolDep T F True:λ(T : *) -> λ(F : *) -> λ(arg : T ) -> λ(P : Bool -> *) -> λ(DepTrue : T -> P True ) -> λ(DepFalse : F -> P False ) -> DepTrue arg
ale nie mogę zapisać funkcji odwrotnej (ani żadnej funkcji w kierunku odwrotnym). Czy to możliwe? Czy powinienem użyć innej reprezentacji BoolDepdo wytworzenia izomorfizmu BoolDep T F True = T?