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.TraversableFunctor
  Functors.Early.Reader.

Import Functor.Notations.

#[local] Generalizable Variable X Y T U G ϕ A B.
#[local] Arguments map F%function_scope {Map}
  {A B}%type_scope f%function_scope _.
#[local] Arguments pure F%function_scope {Pure}
  {A}%type_scope _.
#[local] Arguments mult F%function_scope {Mult}
  {A B}%type_scope _.

(** * Traversable Instance for Certain Functors *)
(**********************************************************************)

(** ** Traversable Instance for <<(E ×)>> *)
(**********************************************************************)
Section TraversableFunctor_prod.

  Generalizable All Variables.

  Context
    (E: Type).

  #[global] Instance Dist_prod: ApplicativeDist (prod E) :=
    fun F Fmap mlt pur A '(x, a) => map F (pair x) a.

  
E: Type

forall (G : Type -> Type) (Map_G : Map G) (Pure_G : Pure G) (Mult_G : Mult G), Applicative G -> forall (A B : Type) (f : A -> B), map (G ∘ prod E) f ∘ dist (prod E) G = dist (prod E) G ∘ map (prod E ∘ G) f
E: Type

forall (G : Type -> Type) (Map_G : Map G) (Pure_G : Pure G) (Mult_G : Mult G), Applicative G -> forall (A B : Type) (f : A -> B), map (G ∘ prod E) f ∘ dist (prod E) G = dist (prod E) G ∘ map (prod E ∘ G) f
E: Type
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B: Type
f: A -> B

map (G ∘ prod E) f ∘ dist (prod E) G = dist (prod E) G ∘ map (prod E ∘ G) f
E: Type
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B: Type
f: A -> B
x: E
a: G A

(map (G ∘ prod E) f ∘ dist (prod E) G) (x, a) = map G (pair (id x)) (map G f a)
E: Type
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B: Type
f: A -> B
x: E
a: G A

map (G ○ prod E) f (map G (pair x) a) = map G (pair (id x)) (map G f a)
E: Type
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B: Type
f: A -> B
x: E
a: G A

map G (map (prod E) f) (map G (pair x) a) = map G (pair (id x)) (map G f a)
E: Type
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B: Type
f: A -> B
x: E
a: G A

(map G (map (prod E) f) ∘ map G (pair x)) a = (map G (pair (id x)) ∘ map G f) a
E: Type
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B: Type
f: A -> B
x: E
a: G A

map G (map (prod E) f ∘ pair x) a = map G (pair (id x) ∘ f) a
reflexivity. Qed.
E: Type

forall (G : Type -> Type) (Map_G : Map G) (Pure_G : Pure G) (Mult_G : Mult G), Applicative G -> Natural (@dist (prod E) Dist_prod G Map_G Pure_G Mult_G)
E: Type

forall (G : Type -> Type) (Map_G : Map G) (Pure_G : Pure G) (Mult_G : Mult G), Applicative G -> Natural (@dist (prod E) Dist_prod G Map_G Pure_G Mult_G)
E: Type
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G

forall (A B : Type) (f : A -> B), map (G ○ prod E) f ∘ dist (prod E) G = dist (prod E) G ∘ map (prod E ○ G) f
E: Type
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B: Type
f: A -> B

map (G ○ prod E) f ∘ dist (prod E) G = dist (prod E) G ∘ map (prod E ○ G) f
eapply (dist_natural_prod f). Qed.
E: Type

forall (G1 G2 : Type -> Type) (H : Map G1) (H0 : Mult G1) (H1 : Pure G1) (H2 : Map G2) (H3 : Mult G2) (H4 : Pure G2) (ϕ : G1 ⇒ G2), ApplicativeMorphism G1 G2 ϕ -> forall A : Type, dist (prod E) G2 ∘ map (prod E) (ϕ A) = ϕ (E * A) ∘ dist (prod E) G1
E: Type

forall (G1 G2 : Type -> Type) (H : Map G1) (H0 : Mult G1) (H1 : Pure G1) (H2 : Map G2) (H3 : Mult G2) (H4 : Pure G2) (ϕ : G1 ⇒ G2), ApplicativeMorphism G1 G2 ϕ -> forall A : Type, dist (prod E) G2 ∘ map (prod E) (ϕ A) = ϕ (E * A) ∘ dist (prod E) G1
E: Type
G1, G2: Type -> Type
H: Map G1
H0: Mult G1
H1: Pure G1
H2: Map G2
H3: Mult G2
H4: Pure G2
ϕ: G1 ⇒ G2
H5: ApplicativeMorphism G1 G2 ϕ
A: Type

dist (prod E) G2 ○ map (prod E) (ϕ A) = ϕ (E * A) ○ dist (prod E) G1
E: Type
G1, G2: Type -> Type
H: Map G1
H0: Mult G1
H1: Pure G1
H2: Map G2
H3: Mult G2
H4: Pure G2
ϕ: G1 ⇒ G2
H5: ApplicativeMorphism G1 G2 ϕ
A: Type
x: E
a: G1 A

map G2 (pair (id x)) (ϕ A a) = ϕ (E * A) (map G1 (pair x) a)
now rewrite appmor_natural. Qed.
E: Type

forall A : Type, dist (prod E) (fun A0 : Type => A0) = id
E: Type

forall A : Type, dist (prod E) (fun A0 : Type => A0) = id
E, A: Type

dist (prod E) (fun A : Type => A) = id
ext [x a]; now cbn. Qed.
E: Type

forall (G1 : Type -> Type) (Map_G : Map G1) (Pure_G : Pure G1) (Mult_G : Mult G1), Applicative G1 -> forall (G2 : Type -> Type) (Map_G0 : Map G2) (Pure_G0 : Pure G2) (Mult_G0 : Mult G2), Applicative G2 -> forall A : Type, dist (prod E) (G1 ∘ G2) = map G1 (dist (prod E) G2) ∘ dist (prod E) G1
E: Type

forall (G1 : Type -> Type) (Map_G : Map G1) (Pure_G : Pure G1) (Mult_G : Mult G1), Applicative G1 -> forall (G2 : Type -> Type) (Map_G0 : Map G2) (Pure_G0 : Pure G2) (Mult_G0 : Mult G2), Applicative G2 -> forall A : Type, dist (prod E) (G1 ∘ G2) = map G1 (dist (prod E) G2) ∘ dist (prod E) G1
E: Type
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
A: Type

dist (prod E) (G1 ○ G2) = map G1 (dist (prod E) G2) ○ dist (prod E) G1
E: Type
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
A: Type
x: E
a: G1 (G2 A)

dist (prod E) (G1 ○ G2) (x, a) = map G1 (dist (prod E) G2) (dist (prod E) G1 (x, a))
E: Type
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
A: Type
x: E
a: G1 (G2 A)

map G1 (map G2 (pair x)) a = map G1 (fun '(x, a) => map G2 (pair x) a) (map G1 (pair x) a)
E: Type
G1: Type -> Type
Map_G: Map G1
Pure_G: Pure G1
Mult_G: Mult G1
H: Applicative G1
G2: Type -> Type
Map_G0: Map G2
Pure_G0: Pure G2
Mult_G0: Mult G2
H0: Applicative G2
A: Type
x: E
a: G1 (G2 A)

map G1 (map G2 (pair x)) a = (map G1 (fun '(x, a) => map G2 (pair x) a) ∘ map G1 (pair x)) a
now rewrite fun_map_map. Qed. #[global] Instance Traversable_prod: Classes.Categorical.TraversableFunctor.TraversableFunctor (prod E) := {| dist_natural := @dist_natural_prod_; dist_morph := @dist_morph_prod; dist_unit := @dist_unit_prod; dist_linear := @dist_linear_prod; |}. End TraversableFunctor_prod. (** * Distribution over Certain Applicative Functors *) (**********************************************************************) (** ** Constant Applicative Functors *) (** To distributive over constant applicative functors, i.e. to fold over monoidal values, we can use the <<Const>> applicative functor. This tends to clutter operations with <<unconst>> operations which get in the way of convenient rewriting. We provide a lighter-weight alternative in this section and some specifications proving equivalence with the <<Const>> versions. *) (**********************************************************************) From Tealeaves Require Import Classes.Monoid Functors.Constant. Section TraversableFunctor_const. #[local] Generalizable Variable M. Context (T: Type -> Type) `{TraversableFunctor T}. (** *** Distribution over <<const>> is agnostic about the tag. *) (** Distribution over a constant applicative functor is agnostic about the type argument ("tag") to the constant functor. On paper it is easy to ignore this, but in Coq this must be proved. Observe this equality is ill-typed if [Const] is used instead. *) (********************************************************************)
T: Type -> Type
H: Map T
H0: ApplicativeDist T
H1: TraversableFunctor T

forall (X M : Type) (op : Monoid_op M) (unit0 : Monoid_unit M), Monoid M -> dist T (const M) = dist T (const M)
T: Type -> Type
H: Map T
H0: ApplicativeDist T
H1: TraversableFunctor T

forall (X M : Type) (op : Monoid_op M) (unit0 : Monoid_unit M), Monoid M -> dist T (const M) = dist T (const M)
T: Type -> Type
H: Map T
H0: ApplicativeDist T
H1: TraversableFunctor T
X, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H2: Monoid M

dist T (const M) = dist T (const M)
T: Type -> Type
H: Map T
H0: ApplicativeDist T
H1: TraversableFunctor T
X, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H2: Monoid M

dist T (const M) = dist T (const M)
T: Type -> Type
H: Map T
H0: ApplicativeDist T
H1: TraversableFunctor T
X, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H2: Monoid M

dist T (const M) = dist T (const M) ∘ id
T: Type -> Type
H: Map T
H0: ApplicativeDist T
H1: TraversableFunctor T
X, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H2: Monoid M

dist T (const M) = dist T (const M) ∘ map T id
T: Type -> Type
H: Map T
H0: ApplicativeDist T
H1: TraversableFunctor T
X, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H2: Monoid M

dist T (const M) = dist T (const M) ∘ map T (map (const M) exfalso)
T: Type -> Type
H: Map T
H0: ApplicativeDist T
H1: TraversableFunctor T
X, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H2: Monoid M

dist T (const M) = dist T (const M) ∘ map (T ∘ const M) exfalso
T: Type -> Type
H: Map T
H0: ApplicativeDist T
H1: TraversableFunctor T
X, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H2: Monoid M

dist T (const M) = map (const M ○ T) exfalso ∘ dist T (const M)
reflexivity. Qed.
T: Type -> Type
H: Map T
H0: ApplicativeDist T
H1: TraversableFunctor T

forall (X Y M : Type) (op : Monoid_op M) (unit0 : Monoid_unit M), Monoid M -> dist T (const M) = dist T (const M)
T: Type -> Type
H: Map T
H0: ApplicativeDist T
H1: TraversableFunctor T

forall (X Y M : Type) (op : Monoid_op M) (unit0 : Monoid_unit M), Monoid M -> dist T (const M) = dist T (const M)
T: Type -> Type
H: Map T
H0: ApplicativeDist T
H1: TraversableFunctor T
X, Y, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H2: Monoid M

dist T (const M) = dist T (const M)
now rewrite (dist_const1 X), (dist_const1 Y). Qed. (** *** Distribution over [Const] vs <<const>> *) (********************************************************************)
T: Type -> Type
H: Map T
H0: ApplicativeDist T
H1: TraversableFunctor T
tag, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H2: Monoid M

unconst ∘ dist T (Const M) ∘ map T mkConst = dist T (const M)
T: Type -> Type
H: Map T
H0: ApplicativeDist T
H1: TraversableFunctor T
tag, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H2: Monoid M

unconst ∘ dist T (Const M) ∘ map T mkConst = dist T (const M)
T: Type -> Type
H: Map T
H0: ApplicativeDist T
H1: TraversableFunctor T
tag, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H2: Monoid M

unconst ∘ dist T (Const M) ∘ map T mkConst = dist T (const M)
T: Type -> Type
H: Map T
H0: ApplicativeDist T
H1: TraversableFunctor T
tag, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H2: Monoid M

dist T (fun _ : Type => M) ∘ map T unconst ∘ map T mkConst = dist T (const M)
T: Type -> Type
H: Map T
H0: ApplicativeDist T
H1: TraversableFunctor T
tag, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H2: Monoid M

dist T (fun _ : Type => M) ∘ (map T unconst ∘ map T mkConst) = dist T (const M)
T: Type -> Type
H: Map T
H0: ApplicativeDist T
H1: TraversableFunctor T
tag, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H2: Monoid M

dist T (fun _ : Type => M) ∘ map T (unconst ∘ mkConst) = dist T (const M)
T: Type -> Type
H: Map T
H0: ApplicativeDist T
H1: TraversableFunctor T
tag, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H2: Monoid M

dist T (fun _ : Type => M) ∘ map T id = dist T (const M)
now rewrite fun_map_id. Qed. End TraversableFunctor_const.