Section contents.
Variable T: Set.
Inductive L: Set := one: T -> L | cons: T -> L -> L.
Fixpoint to_plain (l: L): List.list T :=
match l with one x => List.cons x List.nil | cons x y => List.cons x (to_plain y) end.
Coercion to_plain: L >-> List.list.
Fixpoint from_plain (x: T) (l: List.list T): L:=
match l with
| List.nil => one x
| List.cons h t => cons x (from_plain h t)
end.
Proof with auto.  generalize l x. induction l0... simpl. rewrite IHl0... Qed.
Fixpoint app (a b: L) {struct a}: L :=
match a with
| one x => cons x b
| cons x y => cons x (app y b)
end.
Variable l: L.
Definition head := match l with one x => x | cons x _ => x end.
Definition tail := match l with one _ => List.nil | cons _ x => to_plain x end.
Proof with auto. unfold head. destruct l; left... Qed.
Proof with auto. unfold head. unfold tail. destruct l... Qed.
Add Parametric Morphism (A B: Set): (@map A B)
with signature (@ext_eq A B) ==> (@ext_eq (L A) (L B))
as ne_list_map_ext_eq_morph.
Proof with try reflexivity.
unfold ext_eq.
intros.
induction x0; simpl; rewrite H...
rewrite IHx0...
Qed.

Lemma map_ext (T U: Set) (f g: T -> U): ext_eq f g -> forall l, map f l = map g l.