Built with Alectryon, running Coq+SerAPI v8.17.0+0.17.1. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use instead of Ctrl.

Type families

This file is dully-named Psh.v but in fact is actually about type families, that is maps I → Type for some I : Type.

Notation psh I := (I -> Type).

Pointwise arrows of families.

Definition arrᵢ {I} (X Y : psh I) : Type := forall i, X i -> Y i.
#[global] Infix "⇒ᵢ" := (arrᵢ) (at level 20) : indexed_scope.

A bunch of combinators.

Definition voidᵢ {I : Type} : I -> Type := fun _ => T0.
#[global] Notation "∅ᵢ" := (voidᵢ) : indexed_scope.

Definition sumᵢ {I} (X Y : psh I) : psh I := fun i => (X i + Y i)%type.
#[global] Infix "+ᵢ" := (sumᵢ) (at level 20) : indexed_scope.

Definition prodᵢ {I} (X Y : psh I) : psh I := fun i => (X i * Y i)%type.
#[global] Infix "×ᵢ" := (prodᵢ) (at level 20) : indexed_scope.

Fibers of a function are a particularly import kind of type family.

Inductive fiber {A B} (f : A -> B) : psh B := Fib a : fiber f (f a).
Arguments Fib {A B f}.
Derive NoConfusion for fiber.

Equations fib_extr {A B} {f : A -> B} {b : B} : fiber f b -> A :=
  fib_extr (Fib a) := a .
Equations fib_coh {A B} {f : A -> B} {b : B} : forall p : fiber f b, f (fib_extr p) = b :=
  fib_coh (Fib _) := eq_refl .
Definition fib_constr {A B} {f : A -> B} a : forall b (p : f a = b), fiber f b :=
  eq_rect (f a) (fiber f) (Fib a).

These next two functions form an isomorphism (fiber f ⇒ᵢ X) ≅ (∀ a → X (f a))

Equations fib_into {A B} {f : A -> B} X (h : forall a, X (f a)) : fiber f ⇒ᵢ X :=
  fib_into _ h _ (Fib a) := h a .
Definition fib_from {A B} {f : A -> B} X (h : fiber f ⇒ᵢ X) a : X (f a) :=
  h _ (Fib a).

Using the fiber construction, we can define a "sparse" type family which will be equal to some set at one point of the index and empty otherwise. This will enable us to have an isomorphism (X @ i ⇒ᵢ Y) ≅ (X → Y i).

See the functional pearl by Conor McBride "Kleisli arrows of outrageous fortune" for background on this construction and its use.

#[global] Notation "X @ i" := (fiber (fun (_ : X) => i)) (at level 20) : indexed_scope.

Definition pin {I X} (i : I) : X -> (X @ i) i := Fib.
Definition pin_from {I X Y} {i : I} : ((X @ i) ⇒ᵢ Y) -> (X -> Y i) := fib_from _.
Definition pin_into {I X Y} {i : I} : (X -> Y i) -> (X @ i ⇒ᵢ Y) := fib_into _.

Equations pin_map {I X Y} (f : X -> Y) {i : I} : (X @ i) ⇒ᵢ (Y @ i) :=
  pin_map f _ (Fib x) := Fib (f x) .