In Agda, the type of a forall is determined in such a way that the following all have type Set1 (where Set1 is the type of Set and A has type Set):

Set → A
A → Set
Set → Set

However, the following has type Set:

A → A

I understand that if Set had type Set, there would be contradictions, but I'm failing to see how, if any of the three terms above had type Set, we would have contradictions. Can those be used to prove False? Can they be used to show that Set : Set?

I suppose this is more math than programming. I take it this should have been posted there instead?
–
LeepyShamSep 22 '12 at 22:55

28

Wait, why is this off-topic? This is a fairly common question for Agda or Coq, which although they are often used as proof assistants, are perfectly valid programming languages. His syntax even mirrors Agda, and the post has an Agda tag. It seems rather draconian to close the question as not programming when a tag lists a programming language and it's a valid question in that language.
–
copumpkinSep 25 '12 at 3:30

24

This is a perfectly legitimate question about a type in a programming language that has a perfectly legitimate and well defined answer. How is it an off topic post?
–
Edward KMETTSep 25 '12 at 3:54

2 Answers
2

Now consider () -> Set where () is a unit type. This is clearly isomorphic to Set. So if () -> Set : Set then also Set : Set. In fact, if for any inhabited A we had A -> Set : Set then we could wrap Set into A -> Set using a constant function:

Thanks for the answer, makes sense now. I'm actually pretty sure that Set -> A : Set isn't problematic; they just chose to give it a type of Set1 because it makes more sense. I'm not sure though.
–
LeepyShamSep 23 '12 at 22:39

2

@BrandonPickering I'm not so sure. Intuitively, Set -> Bool is a powerset of Set so it is "even larger" than Set. So if Set -> A : Set for A with at least 2 inhabitants then it seems reasonable that also Set : Set.
–
Petr PudlákSep 24 '12 at 6:24

2

@PetrPudlák: Allowing Set -> A to be in Set seems like it would invite Curry's Paradox instead, which is so devious that GHC can be tricked into attempting to inline its entire (infinitely recursive) proof, as you've discovered yourself.
–
C. A. McCannSep 26 '12 at 13:53

1

@C.A.McCann I tried that, but so far no success. It's a bit different situation - in Curry's Paradox one wraps the datatype into itself, while here one wraps Set into the datatype.
–
Petr PudlákSep 27 '12 at 20:33

I think the best way to understand this is to consider what these things are like as set-theoretic sets, as opposed to as Agda Set. suppose you have A = {a,b,c}. An example of a function f : A → A is a set of pairs, let's say f = { (a,a) , (b,b) , (c,c) } that satisfies some properties that don't matter for this discussion. That is to say, f's elements are the same sort of thing that A's elements are -- they're just values, or pairs of values, nothing too "big".

Now consider the a function F : A → Set. It too is a set of pairs, but its pairs look different: F = { (a,A) , (b,Nat) , (c,Bool) } lets say. The first element of each pair is just an element of A, so it's pretty simple, but the second element of each pair is a Set! That is, the second element is itself a "big" sort of thing. So A → Set couldn't possibly be set, because if it were, then we should be able to have some G : A → Set that looks like G = { (a,G) , ... }. As soon as we can have this, we can get Russell's paradox. So we say A → Set : Set1 instead.

This also addresses the issue of whether or not Set → A should also be in Set1 instead of Set, because the functions in Set → A are just like the functions in A → Set, except that the As are on the right, and the Sets are on the left, of the pairs.