Built with Alectryon, running Coq+SerAPI v8.16.0+0.16.3. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use instead of Ctrl.
From Tealeaves Require Import
  Classes.Categorical.Monad
  Classes.Categorical.RightModule
  Classes.Kleisli.Monad.

Import Kleisli.Monad.Notations.

#[local] Generalizable Variables T A B C.

(** * Categorical Monad to Kleisli Monad *)
(**********************************************************************)

(** ** Derived <<bind>> Operation *)
(**********************************************************************)
Module DerivedOperations.

  #[export] Instance Bind_Categorical (T: Type -> Type)
    `{map_T: Map T}
    `{join_T: Join T}: Bind T T :=
  fun {A B} (f: A -> T B) => join ∘ map (F := T) f.

End DerivedOperations.

(** ** Derived <<bind>> is Compatible with Original <map>> *)
(**********************************************************************)
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T

Compat_Map_Bind T T
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T

Compat_Map_Bind T T
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T

H = DerivedOperations.Map_Bind T T
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B: Type
f: A -> B

H A B f = DerivedOperations.Map_Bind T T A B f
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B: Type
f: A -> B

map f = DerivedOperations.Map_Bind T T A B f
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B: Type
f: A -> B

map f = bind (ret ∘ f)
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B: Type
f: A -> B

map f = join ∘ map (ret ∘ f)
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B: Type
f: A -> B

map f = join ∘ (map ret ∘ map f)
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B: Type
f: A -> B

map f = join ∘ map ret ∘ map f
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B: Type
f: A -> B

map f = id ∘ map f
reflexivity. Qed. Module DerivedInstances. (* Alectryon doesn't like this Import CategoricalToKleisli.Monad.DerivedOperations. *) Import DerivedOperations. Section with_monad. Context `{Categorical.Monad.Monad T}. (** ** <<join>> as <<id ⋆ id>> *) (******************************************************************)
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
H3: Map T
H4: Return T
H5: Join T
H6: Categorical.Monad.Monad T

forall A : Type, join = id ⋆ id
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
H3: Map T
H4: Return T
H5: Join T
H6: Categorical.Monad.Monad T

forall A : Type, join = id ⋆ id
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
H3: Map T
H4: Return T
H5: Join T
H6: Categorical.Monad.Monad T
A: Type

join = id ⋆ id
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
H3: Map T
H4: Return T
H5: Join T
H6: Categorical.Monad.Monad T
A: Type

join = join ∘ map id ∘ id
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
H3: Map T
H4: Return T
H5: Join T
H6: Categorical.Monad.Monad T
A: Type

join = join ∘ id ∘ id
reflexivity. Qed. (** ** Derived Kleisli Monad Laws *) (******************************************************************) (** *** Identity law *) (******************************************************************)
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T

forall A : Type, bind ret = id
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T

forall A : Type, bind ret = id
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A: Type

bind ret = id
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A: Type

join ∘ map ret = id
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A: Type

id = id
reflexivity. Qed. (** *** Composition law *) (******************************************************************)
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T

forall (A B C : Type) (g : B -> T C) (f : A -> T B), bind g ∘ bind f = bind (g ⋆ f)
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T

forall (A B C : Type) (g : B -> T C) (f : A -> T B), bind g ∘ bind f = bind (g ⋆ f)
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B, C: Type
g: B -> T C
f: A -> T B

bind g ∘ bind f = bind (g ⋆ f)
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B, C: Type
g: B -> T C
f: A -> T B

bind g ∘ bind f = bind (bind g ∘ f)
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B, C: Type
g: B -> T C
f: A -> T B

join ∘ map g ∘ (join ∘ map f) = join ∘ map (join ∘ map g ∘ f)
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B, C: Type
g: B -> T C
f: A -> T B

join ∘ map g ∘ (join ∘ map f) = join ∘ (map join ∘ map (map g) ∘ map f)
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B, C: Type
g: B -> T C
f: A -> T B

join ∘ map g ∘ (join ∘ map f) = join ∘ (map join ∘ map (map g)) ∘ map f
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B, C: Type
g: B -> T C
f: A -> T B

join ∘ map g ∘ (join ∘ map f) = join ∘ map join ∘ map (map g) ∘ map f
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B, C: Type
g: B -> T C
f: A -> T B

join ∘ map g ∘ (join ∘ map f) = join ∘ map join ∘ map (map g) ∘ map f
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B, C: Type
g: B -> T C
f: A -> T B

join ∘ map g ∘ (join ∘ map f) = join ∘ join ∘ map (map g) ∘ map f
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B, C: Type
g: B -> T C
f: A -> T B

join ∘ map g ∘ (join ∘ map f) = join ∘ join ∘ map g ∘ map f
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B, C: Type
g: B -> T C
f: A -> T B

join ∘ map g ∘ (join ∘ map f) = join ∘ (join ∘ map g) ∘ map f
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B, C: Type
g: B -> T C
f: A -> T B

join ∘ map g ∘ (join ∘ map f) = join ∘ (map g ∘ join) ∘ map f
reflexivity. Qed. (** *** Unit law *) (******************************************************************)
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T

forall (A B : Type) (f : A -> T B), bind f ∘ ret = f
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T

forall (A B : Type) (f : A -> T B), bind f ∘ ret = f
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B: Type
f: A -> T B

bind f ∘ ret = f
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B: Type
f: A -> T B

join ∘ map f ∘ ret = f
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B: Type
f: A -> T B

join ∘ (map f ∘ ret) = f
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B: Type
f: A -> T B

join ∘ (map f ∘ ret) = f
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B: Type
f: A -> T B

join ∘ (ret ∘ map f) = f
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B: Type
f: A -> T B

join ∘ ret ∘ map f = f
now rewrite (mon_join_ret (T := T)). Qed. #[export] Instance KleisliPreModule_CategoricalPreModule: Kleisli.Monad.RightPreModule T T := {| kmod_bind1 := @mon_bind_id; kmod_bind2 := @mon_bind_bind; |}. #[export] Instance KleisliMonad_CategoricalMonad: Kleisli.Monad.Monad T := {| kmon_bind0 := @mon_bind_comp_ret; |}. End with_monad. End DerivedInstances. (* (** ** Derived laws *) (********************************************************************) Section ToKleisli_laws. Context (T: Type -> Type) `{Categorical.Monad.Monad T}. Generalizable All Variables. Import Kleisli.Monad.Notations. Import ToKleisli. Lemma map_to_bind: forall `(f: A -> B), map T f = bind (ret T B ∘ f). Proof. intros. unfold_ops @Bind_Categorical. rewrite <- (fun_map_map (F := T)). reassociate <-. rewrite (mon_join_map_ret (T := T)). reflexivity. Qed. Corollary bind_map: forall `(g: B -> T C) `(f: A -> B), bind g ∘ map T f = bind (g ∘ f). Proof. intros. unfold transparent tcs. now rewrite <- (fun_map_map (F := T)). Qed. Corollary map_bind: forall `(g: B -> C) `(f: A -> T B), map T g ∘ bind f = bind (map T g ∘ f). Proof. intros. unfold transparent tcs. reassociate <- on left. rewrite (natural). unfold_ops @Map_compose. now rewrite <- (fun_map_map (F := T)). Qed. (** ** Left identity law *) Theorem kleisli_id_l: forall `(f: A -> T B), (@ret T _ B) ⋆1 f = f. Proof. intros. unfold kc1. now rewrite (kmon_bind1 (T := T)). Qed. (** ** Right identity law *) Theorem kleisli_id_r: forall `(g: B -> T C), g ⋆1 (@ret T _ B) = g. Proof. intros. unfold kc1. now rewrite (kmon_bind0 (T := T)). Qed. (** ** Associativity law *) Theorem kleisli_assoc: forall `(h: C -> T D) `(g: B -> T C) `(f: A -> T B), h ⋆1 (g ⋆1 f) = (h ⋆1 g) ⋆1 f. Proof. intros. unfold kc1 at 3. now rewrite <- (kmon_bind2 (T := T)). Qed. End ToKleisli_laws. *) (** * Right modules *) (**********************************************************************) Module ToKleisliRightModule. Import DerivedOperations. Import DerivedInstances. #[export] Instance Bind_RightAction (T U: Type -> Type) `{Map_T: Map U} `{RightAction_TU: RightAction U T}: Bind T U := fun A B (f: A -> T B) => right_action U ∘ map (F := U) f. Section Monad_kleisli_laws. Context (T F: Type -> Type) `{Categorical.RightModule.RightModule F T}. (** *** Identity law *)
T, F: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Map F
H3: RightAction F T
H4: RightModule.RightModule F T

forall A : Type, bind ret = id
T, F: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Map F
H3: RightAction F T
H4: RightModule.RightModule F T

forall A : Type, bind ret = id
T, F: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Map F
H3: RightAction F T
H4: RightModule.RightModule F T
A: Type

bind ret = id
T, F: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Map F
H3: RightAction F T
H4: RightModule.RightModule F T
A: Type

right_action F ∘ map ret = id
now rewrite (mod_action_map_ret). Qed. (** *** Composition law *)
T, F: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Map F
H3: RightAction F T
H4: RightModule.RightModule F T

forall (A B C : Type) (g : B -> T C) (f : A -> T B), bind g ∘ bind f = bind (g ⋆ f)
T, F: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Map F
H3: RightAction F T
H4: RightModule.RightModule F T

forall (A B C : Type) (g : B -> T C) (f : A -> T B), bind g ∘ bind f = bind (g ⋆ f)
T, F: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Map F
H3: RightAction F T
H4: RightModule.RightModule F T
A, B, C: Type
g: B -> T C
f: A -> T B

bind g ∘ bind f = bind (g ⋆ f)
T, F: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Map F
H3: RightAction F T
H4: RightModule.RightModule F T
A, B, C: Type
g: B -> T C
f: A -> T B

bind g ∘ bind f = bind (bind g ∘ f)
T, F: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Map F
H3: RightAction F T
H4: RightModule.RightModule F T
A, B, C: Type
g: B -> T C
f: A -> T B

bind g ∘ bind f = bind (join ∘ map g ∘ f)
T, F: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Map F
H3: RightAction F T
H4: RightModule.RightModule F T
A, B, C: Type
g: B -> T C
f: A -> T B

right_action F ∘ map g ∘ (right_action F ∘ map f) = right_action F ∘ map (join ∘ map g ∘ f)
T, F: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Map F
H3: RightAction F T
H4: RightModule.RightModule F T
A, B, C: Type
g: B -> T C
f: A -> T B

right_action F ∘ map g ∘ (right_action F ∘ map f) = right_action F ∘ (map join ∘ map (map g) ∘ map f)
T, F: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Map F
H3: RightAction F T
H4: RightModule.RightModule F T
A, B, C: Type
g: B -> T C
f: A -> T B

right_action F ∘ map g ∘ (right_action F ∘ map f) = right_action F ∘ (map join ∘ map (map g)) ∘ map f
T, F: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Map F
H3: RightAction F T
H4: RightModule.RightModule F T
A, B, C: Type
g: B -> T C
f: A -> T B

right_action F ∘ map g ∘ (right_action F ∘ map f) = right_action F ∘ (map join ∘ map g) ∘ map f
T, F: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Map F
H3: RightAction F T
H4: RightModule.RightModule F T
A, B, C: Type
g: B -> T C
f: A -> T B

right_action F ∘ map g ∘ (right_action F ∘ map f) = right_action F ∘ map join ∘ map g ∘ map f
T, F: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Map F
H3: RightAction F T
H4: RightModule.RightModule F T
A, B, C: Type
g: B -> T C
f: A -> T B

right_action F ∘ map g ∘ (right_action F ∘ map f) = right_action F ∘ right_action F ∘ map g ∘ map f
T, F: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Map F
H3: RightAction F T
H4: RightModule.RightModule F T
A, B, C: Type
g: B -> T C
f: A -> T B

right_action F ∘ map g ∘ (right_action F ∘ map f) = right_action F ∘ (right_action F ∘ map g) ∘ map f
now rewrite <- (natural (ϕ := @right_action F T _)). Qed. End Monad_kleisli_laws. #[local] Instance Kleisli_RightModule {F T} `{Categorical.RightModule.RightModule F T} : Kleisli.Monad.RightPreModule T F := {| kmod_bind1 := @bind_id T F _ _ _ _ _ _; kmod_bind2 := @bind_bind T F _ _ _ _ _ _; |}. (** ** Specification for <<map>> *) (********************************************************************) Section Monad_suboperations. Context (T: Type -> Type) `{Categorical.Monad.Monad T}. (** *** [map] as a special case of [bind]. *)
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B: Type

forall f : A -> B, map f = bind (ret ∘ f)
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B: Type

forall f : A -> B, map f = bind (ret ∘ f)
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B: Type
f: A -> B

map f = bind (ret ∘ f)
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B: Type
f: A -> B

map f = join ∘ map (ret ∘ f)
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B: Type
f: A -> B

map f = join ∘ (map ret ∘ map f)
T: Type -> Type
H: Map T
H0: Return T
H1: Join T
H2: Categorical.Monad.Monad T
A, B: Type
f: A -> B

map f = join ∘ map ret ∘ map f
now rewrite (mon_join_map_ret (T := T)). Qed. End Monad_suboperations. End ToKleisliRightModule.