Sto sperimentando sistemi di tipo puro nel cubo lambda di Barendregt, in particolare con il più potente, il Calculus of Constructions. Questo sistema ha specie *e BOX. Per la cronaca, di seguito sto usando la sintassi concreta dello Mortestrumento https://github.com/Gabriel439/Haskell-Morte-Library che è vicino al classico calcolo lambda.
Vedo che possiamo emulare tipi induttivi mediante una sorta di codifica simile alla Chiesa (alias isomorfismo di Boehm-Berarducci per tipi di dati algebrici). Per un semplice esempio uso tipo Bool = ∀(t : *) -> t -> t -> tcon i costruttori True = λ(t : *) -> λ(x : t) -> λ(y : t) -> xe False = λ(t : *) -> λ(x : t) -> λ(y : t) -> y.
Vedo che il tipo di funzioni a livello di termine Bool -> Tè isomorfo per coppie di tipi Product T Tcon Product = λ(A : *) -> λ(B : *) -> ∀(t : *) -> (A -> B -> t) -> tparametricità modulo classica per mezzo di una funzione if : Bool -> λ(t : *) -> t -> t -> tche è in realtà identità.
Tutte le domande che seguono saranno sulle rappresentazioni di tipi dipendenti Bool -> *.
Posso dividere
D : Bool -> *in coppia diD TrueeD False. Esiste il modo canonico per creare diDnuovo? Voglio riprodurre l'isomosfismoBool -> T = Product T Tda un analogo della funzioneifa livello di tipo, ma non posso scrivere questa funzione tanto semplice quanto originaleifperché non possiamo passare i tipi in argomenti come i tipi.Uso una specie di tipo induttivo con due costruttori per risolvere la domanda (1). La descrizione di alto livello (stile Agda) è il seguente tipo (utilizzato anziché a livello di tipo
if)data BoolDep (T : *) (F : *) : Bool -> * where DepTrue : T -> BoolDep T F True DepFalse : F -> BoolDep T F Falsecon la seguente codifica in PTS / CoC:
λ(T : *) -> λ(F : *) -> λ(bool : Bool ) -> ∀(P : Bool -> *) -> ∀(DepTrue : T -> P True ) -> ∀(DepFalse : F -> P False ) -> P boolLa mia codifica sopra è corretta?
Posso scrivere i costruttori
BoolDepcome questo codice perDepTrue : ∀(T : *) -> ∀(F : *) -> T -> BoolDep T F True:λ(T : *) -> λ(F : *) -> λ(arg : T ) -> λ(P : Bool -> *) -> λ(DepTrue : T -> P True ) -> λ(DepFalse : F -> P False ) -> DepTrue arg
ma non riesco a scrivere la funzione inversa (o nessuna funzione nella direzione inversa). È possibile? O dovrei usare un'altra rappresentazione per BoolDepprodurre un isomorfismo BoolDep T F True = T?