Estou experimentando sistemas de tipo puro no cubo lambda de Barendregt, especificamente com o mais poderoso, o Cálculo de Construções. Este sistema tem tipos *e BOX. Apenas para constar, abaixo, estou usando a sintaxe concreta da Morteferramenta https://github.com/Gabriel439/Haskell-Morte-Library, que fica próxima ao cálculo lambda clássico.
Vejo que podemos emular tipos indutivos por algum tipo de codificação semelhante à Igreja (também conhecido como isomorfismo de Boehm-Berarducci para tipos de dados algébricos). Para um exemplo simples, eu uso type Bool = ∀(t : *) -> t -> t -> tcom os construtores True = λ(t : *) -> λ(x : t) -> λ(y : t) -> xe False = λ(t : *) -> λ(x : t) -> λ(y : t) -> y.
Vejo que o tipo de funções de nível de termo Bool -> Té isomórfico para pares de tipo Product T Tcom Product = λ(A : *) -> λ(B : *) -> ∀(t : *) -> (A -> B -> t) -> tparametricidade clássica de módulo por meio de função if : Bool -> λ(t : *) -> t -> t -> tque é de fato identidade.
Todas as perguntas abaixo serão sobre representações de tipos dependentes Bool -> *.
Eu posso dividir
D : Bool -> *em par deD TrueeD False. Existe a maneira canônica de criarDnovamente? Quero reproduzir o isomosfismoBool -> T = Product T Tpor um análogo de funçãoifno nível de tipo, mas não posso escrever essa função tão simples quanto o original,ifporque não podemos passar tipos em argumentos como tipos.Eu uso um tipo de tipo indutivo com dois construtores para resolver a questão (1). A descrição de alto nível (estilo Agda) é o seguinte tipo (usado em vez do nível de tipo
if)data BoolDep (T : *) (F : *) : Bool -> * where DepTrue : T -> BoolDep T F True DepFalse : F -> BoolDep T F Falsecom a seguinte codificação em PTS / CoC:
λ(T : *) -> λ(F : *) -> λ(bool : Bool ) -> ∀(P : Bool -> *) -> ∀(DepTrue : T -> P True ) -> ∀(DepFalse : F -> P False ) -> P boolMinha codificação acima está correta?
Eu posso escrever os construtores
BoolDepcomo 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
mas não posso escrever a função inversa (ou qualquer função na direção inversa). É possível? Ou devo usar outra representação para BoolDepproduzir um isomorfismo BoolDep T F True = T?