Section ListPairs.
Variables (A : Type) (B : Type).
(** [split] derives two lists from a list of pairs *)
Fixpoint split (l:list (A*B)) : list A * list B :=
match l with
| [] => ([], [])
| (x,y) :: tl => let (left,right) := split tl in (x::left, y::right)
end.
(** [combine] is the opposite of [split]. Lists given to [combine] are meant to be of same length. If not, [combine] stops on the shorter list *)
Fixpoint combine (l : list A) (l' : list B) : list (A*B) :=
match l,l' with
| x::tl, y::tl' => (x,y)::(combine tl tl')
| _, _ => nil
end.

Lemma split_combine : forall (l: list (A*B)),
let (l1,l2) := split l in combine l1 l2 = l.