Definition semi_group_fold {A: Type} (default: A) (f: A -> A -> A) (l: list A): A :=
match l with
| nil => default
| a :: l0 => fold_left f l0 a
end.
Section ListFun1'.
Context {A: Type}.
Context {RA: relation A}.
Context {EqRA: Equivalence RA}.
Instance proper_semi_group_fold: forall (f: A -> A -> A) (default: A) {Proper_f: Proper (equiv ==> equiv ==> equiv) f}, Proper (Forall2 equiv ==> equiv) (semi_group_fold default f).

Lemma semi_group_fold_concat: forall {f} {Proper_f: Proper (equiv ==> equiv ==> equiv) f} (default: A) ls,
(forall x y z, f (f x y) z === f x (f y z)) ->
Forall not_nil ls ->
semi_group_fold default f (concat ls) === semi_group_fold default f (map (semi_group_fold default f) ls).