Estoy experimentando con sistemas de tipo puro en el cubo lambda de Barendregt, específicamente con el más poderoso, el cálculo de construcciones. Este sistema tiene géneros *
y BOX
. Solo para el registro, a continuación estoy usando la sintaxis concreta de la Morte
herramienta https://github.com/Gabriel439/Haskell-Morte-Library que está cerca del cálculo lambda clásico.
Veo que podemos emular tipos inductivos mediante algún tipo de codificación similar a la Iglesia (también conocido como isomorfismo Boehm-Berarducci para tipos de datos algebraicos). Para un ejemplo simple, uso type Bool = ∀(t : *) -> t -> t -> t
con los constructores True = λ(t : *) -> λ(x : t) -> λ(y : t) -> x
y False = λ(t : *) -> λ(x : t) -> λ(y : t) -> y
.
Veo que el tipo de funciones de nivel de término Bool -> T
es isomorfo a pares de tipos Product T T
con Product = λ(A : *) -> λ(B : *) -> ∀(t : *) -> (A -> B -> t) -> t
paramétrica de módulo clásico por medio de una función if : Bool -> λ(t : *) -> t -> t -> t
que en realidad es identidad.
Todas las preguntas a continuación serán sobre representaciones de tipos dependientes Bool -> *
.
Me puedo dividir
D : Bool -> *
en par deD True
yD False
. ¿Existe la forma canónica de crear deD
nuevo? Quiero reproducir el isomosfismoBool -> T = Product T T
mediante un análogo de funciónif
a nivel de tipo, pero no puedo escribir esta función tan simple como originalif
porque no podemos pasar tipos en argumentos como tipos.Utilizo una especie de tipo inductivo con dos constructores para resolver la pregunta (1). La descripción de alto nivel (estilo Agda) es el siguiente tipo (se utiliza en lugar del nivel de tipo
if
)data BoolDep (T : *) (F : *) : Bool -> * where DepTrue : T -> BoolDep T F True DepFalse : F -> BoolDep T F False
con la siguiente codificación en PTS / CoC:
λ(T : *) -> λ(F : *) -> λ(bool : Bool ) -> ∀(P : Bool -> *) -> ∀(DepTrue : T -> P True ) -> ∀(DepFalse : F -> P False ) -> P bool
¿Mi codificación anterior es correcta?
Puedo escribir los constructores de
BoolDep
este código paraDepTrue : ∀(T : *) -> ∀(F : *) -> T -> BoolDep T F True
:λ(T : *) -> λ(F : *) -> λ(arg : T ) -> λ(P : Bool -> *) -> λ(DepTrue : T -> P True ) -> λ(DepFalse : F -> P False ) -> DepTrue arg
pero no puedo escribir la función inversa (o cualquier función en la dirección inversa). ¿Es posible? ¿O debería usar otra representación para BoolDep
producir un isomorfismo BoolDep T F True = T
?