Right now I have a definition of commute in Coq as:
Definition circ {X Y Z:Type} (f : Y -> Z) (g : X -> Y) : X -> Z := fun z => f (g z).
Infix "@@" := circ (at level 60, right associativity).
Definition funcEq {X Y:Type} (f g : X -> Y) := forall x:X, f x = g x.
Infix "==" := funcEq (at level 60, right associativity).
Definition commute {X:Type} (f : X -> X) (g : X -> X) : Prop := (f @@ g) == (g @@ f).
and can thus state and prove a theorem such as forall (X : Type) (f : X -> X), commute (fmap f) reverse for functions fmap f and reverse on lists. But I want a more generalized definition of commutation, to account for arbitrary functions f—one capable of expressing the truth that forall (X Y : Type) (xs : [X]) (f : X -> Y), reverse (fmap f xs) = fmap f (reverse xs). Is there a reasonably elegant way of doing this?