Local Open Scope morphism_scope.
Section Algebras.
Context {C : Category} (T : (C –≻ C)%functor).
(** A T-Algebra in category C for an endo-functor T : C → C is a pair (U, h) where U is an object of C and h : T _o U → U is an arrow in C. *)
Record Algebra : Type :=
{
Alg_Carrier : C;
Constructors : (T _o Alg_Carrier)%object –≻ Alg_Carrier
}.
(** A T-Algebra homomorphism from (U, h) to (U', h') is an arrow g : U → U' such that the following diagram commutes:  # <pre>  T _a g T _o U ——————————————> T _o U' |                      | |                      | |                      | h |                      | h' |                      | |                      | ↓                      ↓ U ————–——————————————> U g </pre> # *)
Record Algebra_Hom (alg alg' : Algebra) : Type :=
{
Alg_map : (Alg_Carrier alg) –≻ (Alg_Carrier alg');
Alg_map_com : ((Constructors alg') ∘ (T _a Alg_map)
= Alg_map ∘ (Constructors alg))%morphism
}.
Arguments Alg_map {_ _} _.
Arguments Alg_map_com {_ _} _.
(** Composition of algebra homomorphisms. The algebra maps are simply composed. *)
Program Definition Algebra_Hom_compose
{alg alg' alg'' : Algebra}
(h : Algebra_Hom alg alg')
(h' : Algebra_Hom alg' alg'')
: Algebra_Hom alg alg''
:=
{|
Alg_map := ((Alg_map h') ∘ (Alg_map h))%morphism
|}.
Next Obligation.

(* Specifications: *)
(** Two algebra maps are equal if their underlying maps are. The commutative diagrams are equated with proof irrelevance. *)
Lemma Algebra_Hom_eq_simplify (alg alg' : Algebra)
(ah ah' : Algebra_Hom alg alg')
: (Alg_map ah) = (Alg_map ah') -> ah = ah'.
(** Composition of algebra homomorphisms is associative. *)
Theorem Algebra_Hom_compose_assoc
{alg alg' alg'' alg''' : Algebra}
(f : Algebra_Hom alg alg')
(g : Algebra_Hom alg' alg'')
(h : Algebra_Hom alg'' alg''') :
(Algebra_Hom_compose f (Algebra_Hom_compose g h))
= (Algebra_Hom_compose (Algebra_Hom_compose f g) h).