在Agda中,forall
的类型的确定方式使得以下所有类型都Set1
{其中Set1
的类型为Set
和{ {1}}的类型为A
}:
Set
但是,以下类型为Set → A
A → Set
Set → Set
:
Set
我理解如果A → A
类型为Set
,则会出现矛盾,但我没有看到如果上述三个术语中的任何一个具有Set
类型,我们会产生矛盾。那些可以用来证明是假的吗?它们可以用于显示Set
吗?
答案 0 :(得分:17)
很明显,Set : Set
会导致矛盾,例如Russell's paradox。
现在考虑() -> Set
其中()
是unit type。这显然与Set
同构。所以如果() -> Set : Set
那么Set : Set
。事实上,如果对于任何有人居住的A
A -> Set : Set
,我们可以使用常量函数将Set
包装到A -> Set
中:
wrap1 : {A : Set} -> Set -> (A -> Set)
wrap1 v = \_ -> v
并在需要时获取值
unwrap1 : {A : Set}(anyInhabitant : A) -> (A -> Set) -> Set
unwrap1 anyInhabitant f = f anyInhabitant
所以我们可以重建罗素的悖论,就好像我们有Set : Set
一样。
同样适用于Set -> Set
,我们可以将Set
包裹到Set -> Set
中:
data Void : Set where
unwrap2 : (Set -> Set) -> Set
unwrap2 f = f Void
wrap2 : Set -> (Set -> Set)
wrap2 v = \_ -> v
我们可以使用任何类型的Set
代替Void
。
我不确定如何使用Set -> A
做类似的事情,但直觉上这似乎比其他类型更有问题,也许别人会知道。
答案 1 :(得分:7)
我认为理解这一点的最好方法是考虑这些事物是什么样的集合理论集,而不是像Agda Set
。假设你有A = {a,b,c}
。函数f : A → A
的一个示例是一组对,假设f = { (a,a) , (b,b) , (c,c) }
满足一些与此讨论无关的属性。也就是说,f
的元素与A
的元素是相同的 - 它们只是值,或者是值对,没有什么太“大”。
现在考虑一个函数F : A → Set
。它也是一组对,但它的对看起来不同:F = { (a,A) , (b,Nat) , (c,Bool) }
让我们说。每对中的第一个元素只是A
的一个元素,所以它非常简单,但每对的 second 元素都是 Set
!也就是说,第二个元素本身就是一个“大”的东西。因此,A → Set
无法设置,因为如果是,那么我们应该能够拥有一些看起来像G : A → Set
的{{1}}。一旦我们能够做到这一点,我们就能得到拉塞尔的悖论。所以我们改为G = { (a,G) , ... }
。
这也解决了A → Set : Set1
是否也应该在Set → A
而不是Set1
的问题,因为Set
中的函数就像Set → A
中的函数一样{1}},除了A → Set
位于右侧,A
位于左侧之外。