如何显示Haskell类型是由一个且只有一个函数居住?

时间:2015-09-15 02:53:23

标签: haskell category-theory type-theory

this answer中,Gabriel Gonzalez展示了如何证明idforall a. a -> a中唯一的居民。为了做到这一点(在最正式的证明迭代中),他使用Yoneda lemma显示该类型与()同构,并且因为()中只有一个值,所以必须是id的类型。总结一下,他的证据是这样的:

  

Yoneda说:

Functor f => (forall b . (a -> b) -> f b) ~ f a
     

如果a = ()f = Identity,则变为:

(forall b. (() -> b) -> b) ~ ()
     

从简单() -> b ~ b开始,LHS基本上是id的类型。

这感觉就像是一个适用于id的“魔术”。我正在尝试为更复杂的函数类型做同样的事情:

(b -> a) -> (a -> b -> c) -> b -> c

但我不知道从哪里开始。我知道它居住在\f g x = g (f x) x,如果你忽略丑陋 / undefined的东西,我很确定没有其他此类功能。

我不认为Gabriel的伎俩会立即中适用于我选择类型的方式。是否有其他方法(同样正式!),我可以用它来显示此类型与()之间的同构?

1 个答案:

答案 0 :(得分:14)

您可以申请sequent calculus

简短示例,类型为a -> a,我们可以构建如:\x -> (\y -> y) x这样的术语,但仍然可以标准化为\x -> x id。在后续的微积分中,系统禁止构造“可还原的”#34;证明。

您的类型为(b -> a) -> (a -> b -> c) -> b -> c,非正式:

f: b -> a
g: a -> b -> c
x: b
--------------
Goal: c

并且还有很多方法可以继续:

apply g

f: b -> a
g: a -> b -> c
x: b
---------------
Subgoal0: a
Subgoal1: b


apply f

f: b -> a
g: a -> b -> c
x: b
---------------
Subgoal0': b
Subgoal1: b


-- For both
apply x

所以最后,似乎g (f x) x是该类型中唯一的居民。

Yoneda引理方法,必须小心实际拥有forall x

 (b -> a) -> (a -> b -> c) -> b -> c
 forall b a. (b -> a) -> b -> forall c. (a -> b -> c) -> c

让我们专注于结束:

 (a -> b -> c) -> c ~ ((a,b) -> c) -> c

这与(a, b)同构,因此整个类型减少为

(b -> a) -> b -> (a, b)

选择f = Compose (Reader b) (,b)

(b -> a) -> f a ~ f b ~ b -> (b,b)

通过HP a = (a,a)仿函数

,这是独一无二的
b -> (b,b) ~ (() -> b) -> HP b ~ HP () ~ ()

编辑第一种方法感觉更加手工波浪,但感觉更直接:鉴于规则有限,如何构建证据,我们可以构建多少证据?< / p>