End ListFun2.
Existing Instance proper_fold_left.
Section ListFun1.
Context {A: Type}.
Context {RA: relation A}.
Context {EqRA: Equivalence RA}.

(* Specifications: *)
Lemma monoid_fold_left_head: forall {f} {Proper_f: Proper (equiv ==> equiv ==> equiv) f} (e: A) a l,
(forall x, f e x === x) ->
(forall x, f x e === x) ->
(forall x y z, f (f x y) z === f x (f y z)) ->
fold_left f (a :: l) e === f a (fold_left f l e).
Lemma monoid_fold_symm: forall {f} {Proper_f: Proper (equiv ==> equiv ==> equiv) f} (e: A) l,
(forall x, f e x === x) ->
(forall x, f x e === x) ->
(forall x y z, f (f x y) z === f x (f y z)) ->
fold_left f l e === fold_right f e l.
Lemma monoid_fold_left_app: forall {f} {Proper_f: Proper (equiv ==> equiv ==> equiv) f} (e: A) l l',
(forall x, f e x === x) ->
(forall x, f x e === x) ->
(forall x y z, f (f x y) z === f x (f y z)) ->
fold_left f (l ++ l') e === f (fold_left f l e) (fold_left f l' e).