在Agda
,Idris
或Haskell
等类型扩展名的语言中,有=
类型,如下所示
data a :~: b where
Refl :: a :~: a
a :~: b
表示a
和b
相同。
可以在calculus of constructions或Morte(这是基于构造计算的编程语言)中定义这样的类型吗?
答案 0 :(得分:12)
CoC中a :~: b
的标准教会编码是:
(a :~: b) =
forall (P :: * -> * -> *).
(forall c :: *. P c c) ->
P a b
Refl
正在
Refl a :: a :~: a
Refl a =
\ (P :: * -> * -> *)
(h :: forall (c::*). P c c) ->
h a
以上表示 types 之间的相等性。对于术语之间的相等性,:~:
关系必须采用其他参数t :: *
,其中a b :: t
。
((:~:) t a b) =
forall (P :: t -> t -> *).
(forall c :: t. P c c) ->
P a b
Refl t a :: (:~:) t a a
Refl t a =
\ (P :: t -> t -> *)
(h :: forall (c :: t). P c c) ->
h a
答案 1 :(得分:1)
id : \/a : *. a -> a
id = \a : *. \x : a. x
eqn : \/a : *. a -> a -> *
eqn = \a : *. \x : a. \y : a. \/p : (a -> *). p x -> p y
refl : \/a : *. \/x : a. eqn a x x
refl = \a : *. \x : a. \p : (a -> *). id (p x)
其中\/
是pi构造函数,\
是lambda构造函数。
我认为Church-Scott编码的想法是将类型定义为消除规则,将构造函数定义为引入规则。
either
是一个很好的例子:
either : * -> * -> *
either = \a : *. \b : *. \/r : *. (a -> r) -> (b -> r) -> r
left : \/a : *. \/b : *. a -> either a b
left = \a : *. \b : *. \x : a. \r : *. \left1 : (a -> r). \right1 : (b -> r). left1 x
right : \/a : *. \/b : *. b -> either a b
right = \a : *. \b : *. \y : b. \r : *. \left1 : (a -> r). \right1 : (b -> r). right1 y
either
被定义为析取的消除规则。
按照这个想法,eqn a x y
必须定义为liebniz规则\/p : (a -> *). p x -> p y
,因为方程式的消除规则是liebniz规则。
+)1 != 0
的证明:
bottom : *
bottom = \/r : *. r
nat : *
nat = \/r : *. r -> (r -> r) -> r
zero : nat
zero = \r : *. \z : r. \s : (r -> r). z
succ : nat -> nat
succ = \n : nat. \r : *. \z : r. \s : (r -> r). s (n r z s)
id : \/a : *. a -> a
id = \a : *. \x : a. x
eqn : \/a : *. a -> a -> *
eqn = \a : *. \x : a. \y : a. \/p : (a -> *). p x -> p y
refl : \/a : *. \/x : a. eqn a x x
refl = \a : *. \x : a. \p : (a -> *). id (p x)
goal : eqn nat (succ zero) zero -> bottom
goal = \one_is_zero : (\/p : (nat -> *). p (succ zero) -> p zero). \r : *. one_is_zero (\n : nat. n * r (\a : *. r -> a)) (id r)