Dependent Types
In type theory, an ordinary function is written as:
which has a fixed codomain \(B\). However, we often wish the codomain to vary depending on the input. This leads to the notion of a type family:
meaning that for each \(x : A\), the type \(B(x)\) lives in some universe \(\mathcal{U}\).
From the categorical perspective, such a type family corresponds to a Grothendieck fibration:
Specifically, viewing \(B\) as a functor from a discrete category on \(A\) to the category of types \(\mathcal{U}\), we can apply the Grothendieck construction to obtain the total category:
whose objects are pairs \((x, y)\) with \(x : A\) and \(y : B(x)\). The projection
forms a canonical fibration over \(A\), organizing the fibers \(B(x)\) into a single category.
In dependent type theory, we describe such fibrations using two dual constructions: \(\Sigma\)-types and \(\Pi\)-types.
\(\Sigma\)-Type (Dependent Pair Type)
A dependent pair type is written as:
This represents the total space of the type family \(B(x)\): a value of this type is a pair \(\langle x, y \rangle\) where \(x : A\) and \(y : B(x)\).
This directly aligns with the Grothendieck construction:
which collects all the fibers \(B(x)\) into a unified structure over the base type \(A\).
From the perspective of Martin-Löf Type Theory, the fact that \(\Sigma\)-type describes the total space in category theory is precisely what makes it correspond to existential quantification:
\[ \sum_{x:A} B(x) \quad \simeq \quad \exists x : A.\ B(x) \]That is, an inhabitant of this type is a witness that there exists an \(x \in A\) such that \(B(x)\) holds.
\(\Pi\)-Type (Dependent Function Type)
A dependent function type is written as:
This denotes a function that, for every \(x : A\), returns an element in \(B(x)\).
Categorically, given the fibration \(p : \int_{x \in A} B(x) \to A\) induced by the type family \(B\), a dependent function \(f : \prod_{x:A} B(x)\) corresponds to a section of the projection \(p\):
That is, \(f\) selects a coherent element \(f(x) \in B(x)\) for each \(x \in A\), forming a global choice over the fibers.
From the perspective of Martin-Löf Type Theory, the \(\Pi\)-type corresponds to universal quantification because it describes a function that, for every \(x : A\), produces an element of \(B(x)\). In categorical terms, this means specifying a coherent choice of an element in each fiber \(B(x)\) over the base \(A\) — that is, a global section.
\[ \prod_{x:A} B(x) \quad \simeq \quad \forall x : A.\ B(x) \]Thus, an inhabitant of this type provides a method (or witness) that, for every \(x \in A\), supplies a corresponding \(y : B(x)\), thereby verifying the truth of \(B(x)\) for all \(x\).
Syntax
Corresponding to the logic of \(\Sigma\)-type and \(\Pi\)-type, Arch
features both structures (dependent pairs) and dependent functions.
- Based on the \(\Sigma\)-type, a structure in
Arch
describes, from the perspective of the total space, a type \(A : \mathcal{U}\) together with a type family \(B : A \to \mathcal{U}\). By packaging elements as pairs \((a, b)\) with \(a : A\) and \(b : B(a)\), possibly in nested form, structures naturally express complex chains of dependency, corresponds to the total space in the Grothendieck construction. - In contrast, the \(\Pi\)-type is used to describe a coherent selection of elements from the family \(B\) over \(A\), that is, a section. This can be realized in two ways:
- By projecting a dependent field from a structure.
- Or by directly constructing a section from the base \(A\) to the total space, i.e., by defining a dependent function.