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 Export
Classes.Monoid
Functors.Early.Reader.From Tealeaves Require Import
Classes.Kleisli.Monad
Classes.Kleisli.Comonad
Classes.Categorical.Monad
Classes.Categorical.Comonad
Classes.Categorical.Bimonad.Import Product.Notations.Import Functor.Notations.Import Monoid.Notations.Import Categorical.Monad.Notations.Import Categorical.Comonad.Notations.Import Kleisli.Monad.Notations.Import Kleisli.Comonad.Notations.#[local] Generalizable VariablesW T F A M.(** * Writer monad *)(**********************************************************************)(** ** Categorical instance *)(** In the even that [A] is a monoid, the product functor forms a monad. The return operation maps <<b>> to <<(1, b)>> where <<1>> is the monoid unit. The join operation monoidally combines the two monoid values. *)(**********************************************************************)Sectionwriter_monad.Context
`{Monoid M}.#[export] InstanceJoin_writer: Join (prod M) :=
fun (A: Type) (p: M * (M * A)) =>
map_fst (uncurry (@monoid_op M _)) (α^-1 p).#[export] InstanceReturn_writer: Return (prod M) :=
funA (a: A) => (Ƶ, a).
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
Natural (@ret (prod M) Return_writer)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
Natural (@ret (prod M) Return_writer)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
forall (AB : Type) (f : A -> B),
map f ∘ η = η ∘ map f
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A, B: Type f: A -> B
map f ∘ η = η ∘ map f
now ext a.Qed.
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
Natural (@join (prod M) Join_writer)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
Natural (@join (prod M) Join_writer)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
forall (AB : Type) (f : A -> B),
map f ∘ μ = μ ∘ map f
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A, B: Type f: A -> B
map f ∘ μ = μ ∘ map f
now ext [x [x' a]].Qed.#[export, program] InstanceMonad_Categorical_writer:
Monad (prod M).Solve Obligations with
(intros; unfold transparent tcs; ext p;
unfold compose in *; destruct_all_pairs;
cbn; now simpl_monoid).Endwriter_monad.(** ** Tensor Strength Makes any <<T ∘ (W ×)>> a Monad *)(**********************************************************************)#[export] InstanceBeckDistribution_strength
(W: Type) (T: Type -> Type)
`{Map_T: Map T}:
BeckDistribution (W ×) T := (@strength T _ W).Sectionstrength_as_writer_distributive_law.Import Strength.Notations.Context
`{Monoid W}.
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W F: Type -> Type Map_F: Map F H0: Functor F
forallA : Type, σ ∘ η = map (η)
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W F: Type -> Type Map_F: Map F H0: Functor F
forallA : Type, σ ∘ η = map (η)
reflexivity.Qed.
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W F: Type -> Type Map_F: Map F H0: Functor F
forallA : Type, σ ∘ μ = map (μ) ∘ σ ∘ map (σ)
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W F: Type -> Type Map_F: Map F H0: Functor F
forallA : Type, σ ∘ μ = map (μ) ∘ σ ∘ map (σ)
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W F: Type -> Type Map_F: Map F H0: Functor F A: Type
σ ∘ μ = map (μ) ∘ σ ∘ map (σ)
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W F: Type -> Type Map_F: Map F H0: Functor F A: Type w1, w2: W t: F A
now ext [w1 [w2 a]].Qed.#[export] InstanceBimonad_Writer: Bimonad (W ×) :=
{| bimonad_monad := Monad_Categorical_writer;
bimonad_comonad := Comonad_reader W;
Bimonad.bimonad_dist_counit_l := @bimonad_dist_counit_l;
Bimonad.bimonad_dist_counit_r := @bimonad_dist_counit_r;
Bimonad.bimonad_distributive_law := BeckDistributiveLaw_strength;
Bimonad.bimonad_cup := @bimonad_cup;
Bimonad.bimonad_cap := @bimonad_cap;
Bimonad.bimonad_baton := @bimonad_baton;
Bimonad.bimonad_butterfly := @bimonad_butterfly;
|}.Endwriter_bimonad_instance.(** ** Kleisli Monad Instance *)(**********************************************************************)Sectionwriter_monad.Context
`{Monoid W}.#[export] InstanceReturn_Writer: Return (W ×) :=
funA (a: A) => (Ƶ, a).#[export] InstanceBind_Writer: Bind (W ×) (W ×) :=
funAB (f: A -> W * B) (p: W * A) =>
map_fst (uncurry (@monoid_op W _)) (α^-1 (map_snd f p)).
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W
Natural (@ret (prod W) Return_Writer)
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W
Natural (@ret (prod W) Return_Writer)
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W
forall (AB : Type) (f : A -> B),
map f ∘ η = η ∘ map f
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B: Type f: A -> B
map f ∘ η = η ∘ map f
now ext a.Qed.
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W
forall (AB : Type) (f : A -> W * B), bind f ∘ η = f
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W
forall (AB : Type) (f : A -> W * B), bind f ∘ η = f
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B: Type f: A -> W * B
bind f ∘ η = f
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B: Type f: A -> W * B a: A
(bind f ∘ η) a = f a
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B: Type f: A -> W * B a: A
bind f (η a) = f a
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B: Type f: A -> W * B a: A
map_fst (uncurry monoid_op) (α^-1 (map_snd f (Ƶ, a))) =
f a
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B: Type f: A -> W * B a: A
map_fst (uncurry monoid_op)
(let (y, z) := f a in (id Ƶ, y, z)) = f a
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B: Type f: A -> W * B a: A w: W b: B
map_fst (uncurry monoid_op) (id Ƶ, w, b) = (w, b)
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B: Type f: A -> W * B a: A w: W b: B
(id Ƶ ● w, id b) = (w, b)
now simpl_monoid.Qed.
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W
forallA : Type, bind (η) = id
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W
forallA : Type, bind (η) = id
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A: Type
bind (η) = id
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A: Type m: W a: A
bind (η) (m, a) = id (m, a)
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A: Type m: W a: A
map_fst (uncurry monoid_op)
(α^-1 (map_snd (funa : A => (Ƶ, a)) (m, a))) =
id (m, a)
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A: Type m: W a: A
(id m ● Ƶ, id a) = id (m, a)
now simpl_monoid.Qed.
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W
forall (ABC : Type) (g : B -> W * C)
(f : A -> W * B), bind g ∘ bind f = bind (g ⋆ f)
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W
forall (ABC : Type) (g : B -> W * C)
(f : A -> W * B), bind g ∘ bind f = bind (g ⋆ f)
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B, C: Type g: B -> W * C f: A -> W * B
bind g ∘ bind f = bind (g ⋆ f)
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B, C: Type g: B -> W * C f: A -> W * B m: W a: A
(bind g ∘ bind f) (m, a) = bind (g ⋆ f) (m, a)
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B, C: Type g: B -> W * C f: A -> W * B m: W a: A
((funp : W * B =>
map_fst (uncurry monoid_op) (α^-1 (map_snd g p)))
∘ (funp : W * A =>
map_fst (uncurry monoid_op) (α^-1 (map_snd f p))))
(m, a) =
map_fst (uncurry monoid_op)
(α^-1 (map_snd (g ⋆ f) (m, a)))
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B, C: Type g: B -> W * C f: A -> W * B m: W a: A
map_fst (uncurry monoid_op)
(α^-1
(map_snd g
(map_fst (uncurry monoid_op)
(α^-1 (map_snd f (m, a)))))) =
map_fst (uncurry monoid_op)
(α^-1
(map_snd
(funa : A =>
map_fst (uncurry monoid_op)
(α^-1 (map_snd g (f a)))) (m, a)))
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B, C: Type g: B -> W * C f: A -> W * B m: W a: A
map_fst (uncurry monoid_op)
(α^-1
(map_snd g
(map_fst (uncurry monoid_op)
(let (y, z) := f a in (id m, y, z))))) =
map_fst (uncurry monoid_op)
(let (y, z) :=
map_fst (uncurry monoid_op)
(α^-1 (map_snd g (f a))) in
(id m, y, z))
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B, C: Type g: B -> W * C f: A -> W * B m: W a: A
map_fst (uncurry monoid_op)
(α^-1
(map_snd g
(map_fst (uncurry monoid_op)
(let (y, z) := f a in (m, y, z))))) =
map_fst (uncurry monoid_op)
(let (y, z) :=
map_fst (uncurry monoid_op)
(α^-1 (map_snd g (f a))) in
(m, y, z))
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B, C: Type g: B -> W * C f: A -> W * B m: W a: A w: W b: B
map_fst (uncurry monoid_op)
(α^-1
(map_snd g
(map_fst (uncurry monoid_op) (m, w, b)))) =
map_fst (uncurry monoid_op)
(let (y, z) :=
map_fst (uncurry monoid_op)
(α^-1 (map_snd g (w, b))) in
(m, y, z))
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B, C: Type g: B -> W * C f: A -> W * B m: W a: A w: W b: B
map_fst (uncurry monoid_op)
(let (y, z) := g (id b) in (m ● w, y, z)) =
map_fst (uncurry monoid_op)
(let (y, z) :=
map_fst (uncurry monoid_op)
(let (y, z) := g b in (id w, y, z)) in
(m, y, z))
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B, C: Type g: B -> W * C f: A -> W * B m: W a: A w: W b: B
map_fst (uncurry monoid_op)
(let (y, z) := g b in (m ● w, y, z)) =
map_fst (uncurry monoid_op)
(let (y, z) :=
map_fst (uncurry monoid_op)
(let (y, z) := g b in (w, y, z)) in
(m, y, z))
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B, C: Type g: B -> W * C f: A -> W * B m: W a: A w: W b: B w0: W c: C
map_fst (uncurry monoid_op) (m ● w, w0, c) =
map_fst (uncurry monoid_op)
(let (y, z) :=
map_fst (uncurry monoid_op) (w, w0, c) in
(m, y, z))
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B, C: Type g: B -> W * C f: A -> W * B m: W a: A w: W b: B w0: W c: C
((m ● w) ● w0, id c) = (m ● (w ● w0), id (id c))
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B, C: Type g: B -> W * C f: A -> W * B m: W a: A w: W b: B w0: W c: C
((m ● w) ● w0, c) = (m ● (w ● w0), c)
now simpl_monoid.Qed.#[export] InstanceRightPreModule_writer:
Kleisli.Monad.RightPreModule (W ×) (W ×) :=
{| kmod_bind1 := Writer_kmon_bind1;
kmod_bind2 := Writer_kmon_bind2;
|}.#[export] InstanceMonad_writer: Kleisli.Monad.Monad (W ×) :=
{| kmon_bind0 := Writer_kmon_bind0;
|}.(** ** Miscellaneous Properties *)(********************************************************************)
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A: Type
forallw : W, extract ∘ pair w = id
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A: Type
forallw : W, extract ∘ pair w = id
reflexivity.Qed.
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A: Type
forallw : W, extract ∘ incr w = extract
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A: Type
forallw : W, extract ∘ incr w = extract
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A: Type w: W
extract ∘ incr w = extract
now ext [w' a].Qed.
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A: Type
forallw : W, extract ⦿ w = extract
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A: Type
forallw : W, extract ⦿ w = extract
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A: Type w: W
extract ⦿ w = extract
now ext [w' a].Qed.
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B: Type f: A -> B
forallw : W, (f ∘ extract) ⦿ w = f ∘ extract
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B: Type f: A -> B
forallw : W, (f ∘ extract) ⦿ w = f ∘ extract
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B: Type f: A -> B w: W
(f ∘ extract) ⦿ w = f ∘ extract
now ext [w' a].Qed.
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B: Type
forall (f : W * A -> B) (w : W),
f ⦿ w ∘ η = f ∘ pair w
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B: Type
forall (f : W * A -> B) (w : W),
f ⦿ w ∘ η = f ∘ pair w
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B: Type f: W * A -> B w: W
f ⦿ w ∘ η = f ∘ pair w
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B: Type f: W * A -> B w: W a: A
(f ⦿ w ∘ η) a = (f ∘ pair w) a
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B: Type f: W * A -> B w: W a: A
f (op w unit0, a) = f (w, a)
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W A, B: Type f: W * A -> B w: W a: A
f (w ● Ƶ, a) = f (w, a)
now simpl_monoid.Qed.
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W op0: Monoid_op W unit1: Monoid_unit W H0: Monoid W
forallA : Type, uncurry incr = μ
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W op0: Monoid_op W unit1: Monoid_unit W H0: Monoid W
forallA : Type, uncurry incr = μ
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W op0: Monoid_op W unit1: Monoid_unit W H0: Monoid W A: Type
uncurry incr = μ
W: Type op: Monoid_op W unit0: Monoid_unit W H: Monoid W op0: Monoid_op W unit1: Monoid_unit W H0: Monoid W A: Type w1, w2: W a: A