module Polymorphism; type Pair (A : Type) (B : Type) := mkPair : A → B → Pair A B; type Nat := zero : Nat | suc : Nat → Nat; type List (A : Type) := nil : List A | cons : A → List A → List A; type Bool := false : Bool | true : Bool; id : (A : Type) → A → A; id _ a := a; terminating undefined : (A : Type) → A; undefined A := undefined A; add : Nat → Nat → Nat; add zero b := b; add (suc a) b := suc (add a b); nil' : (E : Type) → List E; nil' A := nil; -- currying nil'' : (E : Type) → List E; nil'' E := nil; fst : (A : Type) → (B : Type) → Pair A B → A; fst _ _ (mkPair a b) := a; p : Pair Bool Bool; p := mkPair true false; swap : (A : Type) → (B : Type) → Pair A B → Pair B A; swap A B (mkPair a b) := mkPair b a; curry : (A : Type) → (B : Type) → (C : Type) → (Pair A B → C) → A → B → C; curry A B C f a b := f (mkPair a b) ; ap : (A : Type) → (B : Type) → (A → B) → A → B; ap A B f a := f a; ite : (A : Type) → Bool → A → A → A; ite _ true tt _ := tt; ite _ false _ ff := ff; headDef : (A : Type) → A → List A → A; headDef _ d nil := d; headDef A _ (cons h _) := h; filter : (A : Type) → (A → Bool) → List A → List A; filter A f nil := nil; filter A f (cons x xs) := ite (List A) (f x) (cons x (filter A f xs)) (filter A f xs); map : (A : Type) → (B : Type) → (A → B) → List A → List B; map A B f nil := nil ; map A B f (cons x xs) := cons (f x) (map A B f xs); zip : (A : Type) → (B : Type) → List A → List B → List (Pair A B); zip A B nil _ := nil; zip A B _ nil := nil; zip A B (cons a as) (cons b bs) := nil; zipWith : (A : Type) → (B : Type) → (C : Type) → (A → B → C) → List A → List B → List C; zipWith A B C f nil _ := nil; zipWith A B C f _ nil := nil; zipWith A B C f (cons a as) (cons b bs) := cons (f a b) (zipWith A B C f as bs); rankn : ((A : Type) → A → A) → Bool → Nat → Pair Bool Nat; rankn f b n := mkPair (f Bool b) (f Nat n); -- currying trankn : Pair Bool Nat; trankn := rankn id false zero; l1 : List Nat; l1 := cons zero nil; pairEval : (A : Type) → (B : Type) → Pair (A → B) A → B; pairEval _ _ (mkPair f x) := f x; main : Nat; main := headDef Nat (pairEval Nat Nat (mkPair (add zero) zero)) (zipWith Nat Nat Nat add l1 l1); end;