Skip to the content.
← Everything has a type Index

Consider three short definitions. Every token in them is doing something specific; each is examined in full below.

def double (n : Nat) : Nat := n * 2

def double (n : Nat) : Nat := n * 2

Mathematical reading. def double (n : Nat) : Nat := n * 2 is nothing more than the ordinary mathematical definition

\[\mathrm{double} : \mathbb{N} \to \mathbb{N}, \qquad \mathrm{double}(n) = 2n,\]

with the signature $\mathrm{double} : \mathbb{N} \to \mathbb{N}$ split across def double (n : Nat) : Nat (domain and codomain, spelled out argument-by-argument rather than as a single arrow), and the equation $\mathrm{double}(n) = 2n$ becomes := n * 2. There is no real difference between writing the domain as one arrow Nat → Nat or as a named binder (n : Nat) : Nat, exactly as $f : A \to B,\ f(a) = \ldots$ and $f = (a \mapsto \ldots) : A \to B$ describe the same function.

def average (a b : Nat) : Nat :=
  let sum := a + b
  sum / 2

def average (a b : Nat) : Nat := let sum := a + b; sum / 2

Mathematical reading. The let is exactly a “let $s := a + b$ in $\ldots$” clause of the kind used constantly in written proofs to name an intermediate quantity:

\[\mathrm{average}(a,b) = \big\lfloor \tfrac{s}{2} \big\rfloor \text{ where } s := a + b,\]

One caveat: this average computes $\lfloor s/2 \rfloor$ (floor division) rather than the true rational average $s/2$, since Nat’s division is truncating. This gap is easy to overlook in ordinary mathematical prose, but Lean forces it to be confronted explicitly: there is no coercion to $\mathbb{Q}$ happening for free.

def identity {α : Type} (x : α) : α := x

def identity {α : Type} (x : α) : α := x

Mathematical reading. identity {α : Type} (x : α) : α := x is the family ${\,\mathrm{id}A : A \to A\,}{A \in \mathbf{Type}}$ indexed over every type $A$ at once. It is precisely the assignment sending each object $A$ of the category to its identity morphism $\mathrm{id}A$, packaged as a single polymorphic definition rather than one definition per $A$. The implicit argument {α : Type} is what makes this a *statement about all $A$ simultaneously* rather than a single fixed function. In category theory one would never write “$\mathrm{id}{\mathbb{Z}}$, $\mathrm{id}_{\mathbb{R}}$, …” one at a time either, but would instead say “for every object $A$, there is an identity morphism $\mathrm{id}_A$,” which is exactly what the universally-quantified, implicitly-inferred {α : Type} expresses.


← Everything has a type Index Next: Dependent types, with examples →
Try Lean
Lean playground · v1.4.18