Library CatSem.CAT.monad_h_morphism
Require Export CatSem.CAT.monad_haskell.
Require Export CatSem.CAT.NT.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Transparent Obligations.
Unset Automatic Introduction.
Require Export CatSem.CAT.NT.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Transparent Obligations.
Unset Automatic Introduction.
definition of a morphism of monads in haskell style
Section Monad_Hom.
Variable C : Cat.
Section Monad_Hom_def.
Variables P Q: Monad C.
Class Monad_Hom_struct (Tau: forall c, P c ---> Q c) := {
monad_hom_kl: forall X Y (f: X ---> P Y),
kleisli f ;; Tau Y == Tau X ;; kleisli (f ;; Tau Y ) ;
monad_hom_weta: forall c:C,
weta c ;; Tau c == weta c
}.
Section lemmata.
Variable Tau : forall c, P c ---> Q c.
Variable H : Monad_Hom_struct Tau.
Lemma mh_weta c : weta c ;; Tau c == weta c.
Proof.
apply H.
Qed.
Lemma mh_kleisli X Y f :
kleisli f ;; Tau Y == Tau X ;; kleisli (f ;; Tau Y ).
Proof.
apply H.
Qed.
End lemmata.
Record Monad_Hom := {
monad_hom:> forall c, P c ---> Q c;
monad_hom_struct :> Monad_Hom_struct monad_hom
}.
Section Monad_Hom_NT.
Variable M : Monad_Hom.
Obligation Tactic := idtac.
Program Instance Monad_Hom_NatTrans : NT_struct (fun c => M c).
Next Obligation.
Proof.
intros c d f.
simpl.
unfold lift.
rewrite (monad_hom_kl (Monad_Hom_struct := M) (f;; weta d)).
apply praecomp.
apply kleisli_oid.
rewrite assoc.
rewrite (monad_hom_weta (Monad_Hom_struct := M)).
cat.
Qed.
Canonical Structure Monad_Hom_NT := Build_NT Monad_Hom_NatTrans.
End Monad_Hom_NT.
End Monad_Hom_def.
Lemma Monad_Hom_equiv (P Q: Monad C) :
Equivalence (A:=Monad_Hom P Q) (fun M N => forall x, M x == N x).
Proof.
intros P Q;
constructor.
unfold Reflexive.
cat.
unfold Symmetric;
intros; apply hom_sym;
auto.
unfold Transitive.
intros.
etransitivity; auto.
Qed.
Definition Monad_Hom_oid (P Q: Monad C) :=
Build_Setoid (Monad_Hom_equiv P Q).
Hint Rewrite monad_hom_kl monad_hom_weta : monad.
Existing Instance monad_hom_struct.
Section Monad_Hom_comp.
Variables P Q R : Monad C.
Variable TT: Monad_Hom P Q.
Variable SS: Monad_Hom Q R.
Obligation Tactic := idtac.
Program Instance Monad_Hom_comp_struct :
Monad_Hom_struct (fun c => TT c ;; SS c).
Next Obligation.
Proof.
intros X Y f; simpl.
rewrite <- assoc.
rewrite (monad_hom_kl); try apply TT.
repeat rewrite assoc.
apply praecomp.
rewrite <- assoc.
rewrite <- monad_hom_kl;
try apply SS.
monad; try apply TT; try apply SS.
Qed.
Next Obligation.
Proof.
intro c.
rewrite <- assoc.
rewrite monad_hom_weta;
monad;
try apply TT;
try apply SS.
Qed.
Canonical Structure Monad_Hom_comp :=
Build_Monad_Hom Monad_Hom_comp_struct.
End Monad_Hom_comp.
Section Monad_Hom_id.
Variable P: Monad C.
Obligation Tactic := monad.
Program Instance Monad_Hom_id_struct :
Monad_Hom_struct (fun c => id (P c)).
Canonical Structure Monad_Hom_id :=
Build_Monad_Hom Monad_Hom_id_struct.
End Monad_Hom_id.
Existing Instance monad_hom_struct.
Obligation Tactic := simpl; intros; try apply assoc; cat.
Program Instance MONAD_struct : Cat_struct (fun P Q => Monad_Hom P Q) := {
mor_oid P Q := Monad_Hom_oid P Q;
id P := Monad_Hom_id P;
comp a b c f g := Monad_Hom_comp f g
}.
Next Obligation.
Proof.
unfold Proper; do 2 red.
simpl.
intros x y H x' y' H' z;
rewrite H;
rewrite H';
cat.
Qed.
Definition MONAD := Build_Cat MONAD_struct.
Section Facts.
Variables P Q:MONAD.
Variable h : P ---> Q.
Existing Instance monad_hom_struct.
Hint Rewrite monad_hom_kl monad_hom_weta : monad.
Lemma monad_hom_lift c d (f: c ---> d) :
lift f ;; h _ == h _ ;; lift f.
Proof.
unfold lift.
monad; apply h.
Qed.
Lemma monad_hom_join (c : C):
join _ ;; h _ == h _ ;; lift (h _ ) ;; join c .
Proof.
unfold join;
monad;
try apply h.
Qed.
End Facts.
End Monad_Hom.
Existing Instance monad_hom_struct.
Existing Instance MONAD_struct.
Existing Instance Monad_Hom_oid.
Existing Instance Monad_Hom_NatTrans.
Hint Rewrite monad_hom_lift monad_hom_join monad_hom_kl
monad_hom_weta: monad.
Coercion Monad_Hom_NatTrans : Monad_Hom >-> NT_struct.