Definition compose {A B C : Type} (f : A -> B) (g : B -> C) : A -> C := fun a : A => g (f a). (* Curly braces make parameters implicit, meaning the type checker tries to infer them. *) Check @compose. (* @ makes implicit parameters explicit. *) (* forall : dependent function type *) Inductive Nat : Type := O : Nat | S : Nat -> Nat. Fixpoint double (n : Nat) : Nat := match n with | O => O | S n => S (S (double n)) end. Print double. (* fix f params : return-type := body *) (* Structural recursion : double is only called on substructures of the parameter *) Inductive Le (n : Nat) : Nat -> Type := Le_refl : Le n n | Le_S (n' : Nat) : Le n n' -> Le n (S n'). Fixpoint minus (m n : Nat) (l : Le m n) : Nat := match l with | Le_refl => O | Le_S n l => minus m n l end. Fixpoint Le_O (n : Nat) : Le O n := match n with | O => Le_refl O | S n => Le_S O n (Le_O n) end. Print Le_O. (* Notice the as clause (and the return clause). *) Fixpoint Le_trans (n n' n'' : Nat) (l : Le n n') (l' : Le n' n'') : Le n n'' := match l' with | Le_refl => l | Le_S n'' l' => Le_S n n'' (Le_trans n n' n'' l l') end. Print Le_trans. (* Notice the in clause. *) Inductive List (A : Type) : Type := nil : List A | cons : A -> List A -> List A. Fixpoint length {A : Type} (l : List A) : Nat := match l with | nil => O | cons _ l => S (length l) end. Inductive Vec (A : Type) : Nat -> Type := empty : Vec A O | prep {n : Nat} : A -> Vec A n -> Vec A (S n). Fixpoint Vec2List {A : Type} {n : Nat} (v : Vec A n) : List A := match v with | empty => nil A | prep _ a v => cons A a (Vec2List v) end. Fixpoint List2Vec {A : Type} (l : List A) : Vec A (length l) := match l as l return Vec A (length l) with | nil => empty A | cons a l => prep A a (List2Vec l) end.