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.Categorical.Applicative
  Classes.Categorical.Monad (Return, ret)
  Classes.Categorical.Comonad (Extract, extract)
  Functors.Early.Batch
  Functors.Early.Reader.

Import Batch.Notations.
Import Product.Notations.
Import Applicative.Notations.

#[local] Generalizable Variables E T A B.

(** * Coalgebraic Decorated Traversable Functors *)
(**********************************************************************)

(** ** The <<toBatch3>> Operation *)
(**********************************************************************)
Class ToBatch3 (E: Type) (T: Type -> Type) :=
  toBatch3: forall A B, T A -> Batch (E * A) B (T B).

#[global] Arguments toBatch3 {E}%type_scope {T}%function_scope
  {ToBatch3} {A B}%type_scope _.

(** ** Operation <<cojoin_Batch3>> *)
(**********************************************************************)
Fixpoint cojoin_Batch3 `{ToBatch3 E T} {A B B' C: Type}
  (b: Batch (E * A) B C): Batch (E * A) B' (Batch (E * B') B C) :=
  match b with
  | Done c => Done (Done c)
  | Step rest (*:Batch (E * A) B (B -> C)*) (e, a)(*:E*A*) =>
      Step (map (F := Batch (E * A) B')
              (fun (continue: Batch (E * B') B (B -> C))
                 (b': B') =>
                 Step continue (e, b')
              ) (cojoin_Batch3 rest:
                Batch (E * A) B' (Batch (E * B') B (B -> C))))
        ((e, a): E * A)
  end.

(** ** <<cojoin_Batch3>> as <<runBatch double_batch3>> *)
(**********************************************************************)
Section section.

  Context
    `{ToBatch3 E T}.

  Definition double_batch3 {A B: Type} (C: Type):
    E * A -> (Batch (E * A) B ∘ Batch (E * B) C) C :=
    fun '(e, a) => (map (F := Batch (E * A) B)
                   (batch (E * B) C ∘ pair e) ∘ batch (E * A) B) (e, a).

  
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, C: Type

forall '(e, a), double_batch3 C (e, a) = Done (batch (E * B) C ∘ pair e) ⧆ (e, a)
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, C: Type

forall '(e, a), double_batch3 C (e, a) = Done (batch (E * B) C ∘ pair e) ⧆ (e, a)
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, C: Type
e: E
a: A

double_batch3 C (e, a) = Done (batch (E * B) C ∘ pair e) ⧆ (e, a)
reflexivity. Qed.
E: Type
T: Type -> Type
H: ToBatch3 E T

forall A B B' : Type, @cojoin_Batch3 E T H A B B' = (fun C : Type => runBatch (double_batch3 B))
E: Type
T: Type -> Type
H: ToBatch3 E T

forall A B B' : Type, @cojoin_Batch3 E T H A B B' = (fun C : Type => runBatch (double_batch3 B))
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B': Type

@cojoin_Batch3 E T H A B B' = (fun C : Type => runBatch (double_batch3 B))
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B', C: Type
b: Batch (E * A) B C

cojoin_Batch3 b = runBatch (double_batch3 B) b
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B', C: Type
c: C

cojoin_Batch3 (Done c) = runBatch (double_batch3 B) (Done c)
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B', C: Type
rest: Batch (E * A) B (B -> C)
e: E
a: A
IHrest: cojoin_Batch3 rest = runBatch (double_batch3 B) rest
cojoin_Batch3 (rest ⧆ (e, a)) = runBatch (double_batch3 B) (rest ⧆ (e, a))
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B', C: Type
c: C

cojoin_Batch3 (Done c) = runBatch (double_batch3 B) (Done c)
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B', C: Type
c: C

Done (Done c) = pure c
reflexivity.
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B', C: Type
rest: Batch (E * A) B (B -> C)
e: E
a: A
IHrest: cojoin_Batch3 rest = runBatch (double_batch3 B) rest

cojoin_Batch3 (rest ⧆ (e, a)) = runBatch (double_batch3 B) (rest ⧆ (e, a))
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B', C: Type
rest: Batch (E * A) B (B -> C)
e: E
a: A
IHrest: cojoin_Batch3 rest = runBatch (double_batch3 B) rest

map (fun continue : Batch (E * B') B (B -> C) => Step continue ○ pair e) (cojoin_Batch3 rest) ⧆ (e, a) = map (compose (map (fun '(f, a) => f a))) (map (compose mult) (map strength_arrow (map (fun c : Batch (E * B') B (B -> C) => (c, batch (E * B') B ∘ pair e ∘ id)) (runBatch (double_batch3 B) rest)))) ⧆ (e, a)
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B', C: Type
rest: Batch (E * A) B (B -> C)
e: E
a: A
IHrest: cojoin_Batch3 rest = runBatch (double_batch3 B) rest

map (fun continue : Batch (E * B') B (B -> C) => Step continue ○ pair e) (cojoin_Batch3 rest) ⧆ (e, a) = (map (compose (map (fun '(f, a) => f a))) ∘ (map (compose mult) ∘ (map strength_arrow ∘ map (fun c : Batch (E * B') B (B -> C) => (c, batch (E * B') B ∘ pair e ∘ id))))) (runBatch (double_batch3 B) rest) ⧆ (e, a)
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B', C: Type
rest: Batch (E * A) B (B -> C)
e: E
a: A
IHrest: cojoin_Batch3 rest = runBatch (double_batch3 B) rest

map (fun continue : Batch (E * B') B (B -> C) => Step continue ○ pair e) (cojoin_Batch3 rest) ⧆ (e, a) = map (compose (map (fun '(f, a) => f a)) ∘ (compose mult ∘ (strength_arrow ∘ (fun c : Batch (E * B') B (B -> C) => (c, batch (E * B') B ∘ pair e ∘ id))))) (runBatch (double_batch3 B) rest) ⧆ (e, a)
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B', C: Type
rest: Batch (E * A) B (B -> C)
e: E
a: A
IHrest: cojoin_Batch3 rest = runBatch (double_batch3 B) rest

map (fun continue : Batch (E * B') B (B -> C) => Step continue ○ pair e) (cojoin_Batch3 rest) = map (compose (map (fun '(f, a) => f a)) ∘ (compose mult ∘ (strength_arrow ∘ (fun c : Batch (E * B') B (B -> C) => (c, batch (E * B') B ∘ pair e ∘ id))))) (runBatch (double_batch3 B) rest)
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B', C: Type
rest: Batch (E * A) B (B -> C)
e: E
a: A
IHrest: cojoin_Batch3 rest = runBatch (double_batch3 B) rest

map (fun continue : Batch (E * B') B (B -> C) => Step continue ○ pair e) (runBatch (double_batch3 B) rest) = map (compose (map (fun '(f, a) => f a)) ∘ (compose mult ∘ (strength_arrow ∘ (fun c : Batch (E * B') B (B -> C) => (c, batch (E * B') B ∘ pair e ∘ id))))) (runBatch (double_batch3 B) rest)
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B', C: Type
rest: Batch (E * A) B (B -> C)
e: E
a: A
IHrest: cojoin_Batch3 rest = runBatch (double_batch3 B) rest

(fun continue : Batch (E * B') B (B -> C) => Step continue ○ pair e) = compose (map (fun '(f, a) => f a)) ∘ (compose mult ∘ (strength_arrow ∘ (fun c : Batch (E * B') B (B -> C) => (c, batch (E * B') B ∘ pair e ∘ id))))
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B', C: Type
rest: Batch (E * A) B (B -> C)
e: E
a: A
IHrest: cojoin_Batch3 rest = runBatch (double_batch3 B) rest
b: Batch (E * B') B (B -> C)
x: B'

b ⧆ (e, x) = (compose (map (fun '(f, a) => f a)) ∘ (compose mult ∘ (strength_arrow ∘ (fun c : Batch (E * B') B (B -> C) => (c, batch (E * B') B ∘ pair e ∘ id))))) b x
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B', C: Type
rest: Batch (E * A) B (B -> C)
e: E
a: A
IHrest: cojoin_Batch3 rest = runBatch (double_batch3 B) rest
b: Batch (E * B') B (B -> C)
x: B'

b ⧆ (e, x) = map (fun '(f, a) => f a) (mult (strength_arrow (b, fun a : B' => batch (E * B') B (e, id a)) x))
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B', C: Type
rest: Batch (E * A) B (B -> C)
e: E
a: A
IHrest: cojoin_Batch3 rest = runBatch (double_batch3 B) rest
b: Batch (E * B') B (B -> C)
x: B'

b ⧆ (e, x) = map (compose (fun '(f, a) => f a)) (map strength_arrow (map (fun c : B -> C => (c, id)) b)) ⧆ (e, id x)
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B', C: Type
rest: Batch (E * A) B (B -> C)
e: E
a: A
IHrest: cojoin_Batch3 rest = runBatch (double_batch3 B) rest
b: Batch (E * B') B (B -> C)
x: B'

b ⧆ (e, x) = map (compose (fun '(f, a) => f a)) ((map strength_arrow ∘ map (fun c : B -> C => (c, id))) b) ⧆ (e, id x)
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B', C: Type
rest: Batch (E * A) B (B -> C)
e: E
a: A
IHrest: cojoin_Batch3 rest = runBatch (double_batch3 B) rest
b: Batch (E * B') B (B -> C)
x: B'

b ⧆ (e, x) = map (compose (fun '(f, a) => f a)) (map (strength_arrow ∘ (fun c : B -> C => (c, id))) b) ⧆ (e, id x)
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B', C: Type
rest: Batch (E * A) B (B -> C)
e: E
a: A
IHrest: cojoin_Batch3 rest = runBatch (double_batch3 B) rest
b: Batch (E * B') B (B -> C)
x: B'

b ⧆ (e, x) = (map (compose (fun '(f, a) => f a)) ∘ map (strength_arrow ∘ (fun c : B -> C => (c, id)))) b ⧆ (e, id x)
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B', C: Type
rest: Batch (E * A) B (B -> C)
e: E
a: A
IHrest: cojoin_Batch3 rest = runBatch (double_batch3 B) rest
b: Batch (E * B') B (B -> C)
x: B'

b ⧆ (e, x) = map (compose (fun '(f, a) => f a) ∘ (strength_arrow ∘ (fun c : B -> C => (c, id)))) b ⧆ (e, id x)
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B', C: Type
rest: Batch (E * A) B (B -> C)
e: E
a: A
IHrest: cojoin_Batch3 rest = runBatch (double_batch3 B) rest
b: Batch (E * B') B (B -> C)
x: B'

b = map (compose (fun '(f, a) => f a) ∘ (strength_arrow ∘ (fun c : B -> C => (c, id)))) b
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B', C: Type
rest: Batch (E * A) B (B -> C)
e: E
a: A
IHrest: cojoin_Batch3 rest = runBatch (double_batch3 B) rest
b: Batch (E * B') B (B -> C)
x: B'

b = map (fun a : B -> C => fst (a, id) ○ snd (a, id)) b
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, B', C: Type
rest: Batch (E * A) B (B -> C)
e: E
a: A
IHrest: cojoin_Batch3 rest = runBatch (double_batch3 B) rest
b: Batch (E * B') B (B -> C)
x: B'

b = id b
reflexivity. Qed.
E: Type
T: Type -> Type
H: ToBatch3 E T

forall A B C : Type, cojoin_Batch3 ∘ batch (E * A) C = double_batch3 C
E: Type
T: Type -> Type
H: ToBatch3 E T

forall A B C : Type, cojoin_Batch3 ∘ batch (E * A) C = double_batch3 C
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, C: Type

cojoin_Batch3 ∘ batch (E * A) C = double_batch3 C
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, C: Type

runBatch (double_batch3 C) ∘ batch (E * A) C = double_batch3 C
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, C: Type
e:= runBatch_batch: forall (G : Type -> Type) (Map_G : Map G) (Pure_G : Pure G) (Mult_G : Mult G), Applicative G -> forall (A B : Type) (f : A -> G B), runBatch f ∘ batch A B = f

runBatch (double_batch3 C) ∘ batch (E * A) C = double_batch3 C
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, C: Type
e: forall (A0 B0 : Type) (f : A0 -> (Batch (E * A) B ∘ Batch (E * B) C) B0), runBatch f ∘ batch A0 B0 = f

runBatch (double_batch3 C) ∘ batch (E * A) C = double_batch3 C
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, C: Type
e: forall f : E * A -> (Batch (E * A) B ∘ Batch (E * B) C) C, runBatch f ∘ batch (E * A) C = f

runBatch (double_batch3 C) ∘ batch (E * A) C = double_batch3 C
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, C: Type
e: runBatch (double_batch3 C) ∘ batch (E * A) C = double_batch3 C

runBatch (double_batch3 C) ∘ batch (E * A) C = double_batch3 C
apply e. Qed.
E: Type
T: Type -> Type
H: ToBatch3 E T

forall A B C : Type, ApplicativeMorphism (Batch (E * A) C) (Batch (E * A) B ∘ Batch (E * B) C) (@cojoin_Batch3 E T H A C B)
E: Type
T: Type -> Type
H: ToBatch3 E T

forall A B C : Type, ApplicativeMorphism (Batch (E * A) C) (Batch (E * A) B ∘ Batch (E * B) C) (@cojoin_Batch3 E T H A C B)
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, C: Type

ApplicativeMorphism (Batch (E * A) C) (Batch (E * A) B ∘ Batch (E * B) C) (@cojoin_Batch3 E T H A C B)
E: Type
T: Type -> Type
H: ToBatch3 E T
A, B, C: Type

ApplicativeMorphism (Batch (E * A) C) (Batch (E * A) B ∘ Batch (E * B) C) (fun C0 : Type => runBatch (double_batch3 C))
apply ApplicativeMorphism_runBatch. Qed. End section. (** ** Typeclass *) (**********************************************************************) Class DecoratedTraversableFunctor (E: Type) (T: Type -> Type) `{ToBatch3 E T} := { dtf_extract: forall (A: Type), extract_Batch ∘ mapfst_Batch (extract (W := (E ×))) ∘ toBatch3 = @id (T A); dtf_duplicate: forall (A B C: Type), cojoin_Batch3 ∘ toBatch3 (A := A) (B := C) = map (F := Batch (E * A) B) (toBatch3) ∘ toBatch3; }.