我正在Barendregt的lambda多维数据集中尝试使用纯类型系统,特别是最强大的系统,即构造微积分。该系统具有排序*
和BOX
。仅出于记录目的,下面我使用Morte
工具https://github.com/Gabriel439/Haskell-Morte-Library的具体语法,该语法与经典的lambda演算很接近。
我看到我们可以通过某种类似于教堂的编码(对于代数数据类型也称为Boehm-Berarducci同构)来模拟归纳类型。作为一个简单的示例,我将type Bool = ∀(t : *) -> t -> t -> t
与构造函数True = λ(t : *) -> λ(x : t) -> λ(y : t) -> x
and一起使用False = λ(t : *) -> λ(x : t) -> λ(y : t) -> y
。
我看到,术语级函数Bool -> T
的类型通过实际上是同一性的函数Product T T
与具有经典Product = λ(A : *) -> λ(B : *) -> ∀(t : *) -> (A -> B -> t) -> t
模参数性的类型对同构if : Bool -> λ(t : *) -> t -> t -> t
。
下面的所有问题都是关于依赖类型的表示Bool -> *
。
我可以拆分
D : Bool -> *
成对D True
和D False
。有没有D
再次创建的规范方法?我想Bool -> T = Product T T
通过if
类型级别的函数的类似物来重现同构,但if
由于我们无法在类型之类的参数中传递类型,因此我无法像原始函数那样编写此函数。我使用一种具有两个构造函数的归纳类型来解决问题(1)。高级描述(Agda样式)是以下类型(用于代替type-level
if
)data BoolDep (T : *) (F : *) : Bool -> * where DepTrue : T -> BoolDep T F True DepFalse : F -> BoolDep T F False
在PTS / CoC中使用以下编码:
λ(T : *) -> λ(F : *) -> λ(bool : Bool ) -> ∀(P : Bool -> *) -> ∀(DepTrue : T -> P True ) -> ∀(DepFalse : F -> P False ) -> P bool
我上面的编码正确吗?
我可以为
BoolDep
以下代码写下构造函数DepTrue : ∀(T : *) -> ∀(F : *) -> T -> BoolDep T F True
:λ(T : *) -> λ(F : *) -> λ(arg : T ) -> λ(P : Bool -> *) -> λ(DepTrue : T -> P True ) -> λ(DepFalse : F -> P False ) -> DepTrue arg
但我不能写下反函数(或任何反方向的函数)。可能吗?还是应该使用其他表示形式BoolDep
来产生同构BoolDep T F True = T
?