Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell `结构微积分中的Refl'thing?_Haskell_Functional Programming_Equality_Dependent Type_Morte - Fatal编程技术网

Haskell `结构微积分中的Refl'thing?

Haskell `结构微积分中的Refl'thing?,haskell,functional-programming,equality,dependent-type,morte,Haskell,Functional Programming,Equality,Dependent Type,Morte,在具有类型扩展名的语言中,例如Agda、Idris或Haskell,有一种类似于以下的=类型 data a :~: b where Refl :: a :~: a a:~:b表示a和b是相同的 这种类型可以在or(基于构造演算的编程语言)中定义吗?CoC中a:~:b的标准Church编码是: (a :~: b) = forall (P :: * -> * -> *). (forall c :: *. P c c) -> P a b Refl

在具有类型扩展名的语言中,例如
Agda
Idris
Haskell
,有一种类似于以下的
=
类型

data a :~: b where
  Refl :: a :~: a
a:~:b
表示
a
b
是相同的


这种类型可以在or(基于构造演算的编程语言)中定义吗?

CoC中
a:~:b
的标准Church编码是:

(a :~: b) =
   forall (P :: * -> * -> *).
      (forall c :: *. P c c) ->
      P a b
Refl
being

Refl a :: a :~: a
Refl a =
   \ (P :: * -> * -> *)
     (h :: forall (c::*). P c c) ->
     h a
以上规定了类型之间的相等性。为了使术语之间相等,关系必须采用附加参数
t:*
,其中
ab::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
其中,
\/
是pi构造函数,
\
是lambda构造函数

我认为Church Scott编码的思想是将类型定义为其消除规则,将其构造函数定义为其引入规则

都是一个很好的例子:

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
被定义为析取的消除规则

根据这个想法,
eqn a x y
必须定义为利布尼兹规则
\/p:(a->*)。Px->Py
,因为方程的消去法则是利布尼兹法则


+)
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)

每个感应类型都可以用CoC编码,但没有相关的依赖消除原理(非依赖消除可用)。(还要注意,
a:~:b
是一种类型,但
Refl
是一个值。)构造演算是lambda立方体的“顶部”。哈斯凯尔、爱格达和伊德里斯“低于”CoC。因此,CoC更具表现力这一简单事实应该是可能的。(有人可能会指出我在这个推论中是否错了?@Bakuriu事实上,Agda/Coq超出了CoC,因为它们也允许具有依赖消除的归纳类型,而CoC缺乏这种类型。Agda还证明了Streicher的公理K,这意味着相同等式的任何两个证明
p,q
必须相等(
p=q
)——在CoC或Coq(又称CiC)中不可用@chi:我还应该注意到Coq中的非指示性
Prop
,以及Agda和Idris中的归纳递归是远远超出lambda立方体的特性。@AndrásKovács有趣。然而,
*
在CoC中不是很有意义吗?很有趣。有没有可能像您在其他语言中所做的那样,从
0:~:1
推导出矛盾?(哦,等等,我明白了。只要做一个等式函数,它返回
()
而不是True,返回
Void
而不是false。我认为这会起作用。)(另外,我明白了这是如何很容易推广到其他GADT。)@PyRulez是的。对于教堂数字,
0fx=x
1fx=fx
(对其他类型参数进行模化)。使用它,您可以使
0(const-True)False=False
1(const-True)False=True
。假设
0:~:1
并取
py=(x(const-True)False)(y(const-True)False)
,我们可以证明
False-True
。你能补充一些解释吗?请看这里您需要
id
做什么?@PyRulez只是为了美女好的。这个定义是对称的吗?@PyRulez是的,是对称的。为了表明定义是对称的,推导
a:://code>,
x:a
y:a
|-
eqn a x y->eqn a y x
就足够了。设
h:eqn a x y
。由于
方程a x y
=
\/p:(a->*)。px->py
,我们可以从
h:\/p:(a->*)导出
eqnax->eqnayx
。Px->Py
,放置
p
:=
\z:a。等式a z x
。应用
reflax:eqnax
,我们得到了
eqnayx
的一个证明。Q.E.D。
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)