In the Lean 4 book called "Theorem Proving in Lean 4" (https://lean-lang.org/theorem_proving_in_lean4/title_page.html), I don't understand a code example about cartesian product types in chapter 2 "Dependent Type Theory".
The example (which I have edited to keep only relevant information) is:
universe u v
def f (α : Type u) (β : α → Type v) (a : α) (b : β a) : (a : α) × β a :=
⟨a, b⟩
def h1 (x : Nat) : Nat :=
(f Type (fun α => α) Nat x).2
#eval h1 5 -- 5
I would have written h1
as below:
def h1 (x : Nat) : Nat :=
(f Nat (fun α => α) x x).2
I don't understand why the first argument of h1
has to be Type
instead of the Nat
concrete type since we told that the type of its first argument type is (α : Type u)
i.e. α
is a type like Nat
. Don't we build pairs of naturals ?
After having read the comment of question Non-trivial examples of dependent sum ($\Sigma$-types) in Lean?, I understand that the first element of the pair has to be a type (and not a natural) which allows us to make the type of the second element depend on it. That brings two questions:
- What is the role of universes
u
andv
used in this example ? Is there an implicit hierarchy likeu < v
oru + 1 = v
? I think the concept of "universe" is not explained in the manual before meeting that example. - Could the type of the second element in the pair depend on a concrete value alone instead of a type ? Would it still be called a cartesian product dependent type ? See below.
def f' (_n : Nat) (β : Nat → Type v) (a : Nat) (b : β a) : (a : Nat) × β a := ⟨a, b⟩
def h1' (x : Nat) : Nat := (f Nat (fun _ => Nat) x x).2
#eval h1' 5 -- 5