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.Functor
Classes.Monoid.From Tealeaves Require Import
Classes.Categorical.Monad
Classes.Categorical.ContainerFunctor
Classes.Kleisli.Monad
Classes.Kleisli.TraversableMonad
Classes.Kleisli.TraversableFunctor.Import Kleisli.TraversableMonad.Notations.Import Kleisli.TraversableFunctor.Notations.Import Kleisli.Monad.Notations.Import List.ListNotations.Import Monoid.Notations.Import Subset.Notations.Import ContainerFunctor.Notations.Import Applicative.Notations.Open Scope list_scope.#[local] Generalizable VariablesA B M ϕ G.(** * Automation: <<simpl_list>> *)(**********************************************************************)Create HintDb tea_list.Tactic Notation"simpl_list" :=
(autorewrite with tea_list).Tactic Notation"simpl_list""in" hyp(H) :=
(autorewrite with tea_list H).Tactic Notation"simpl_list""in""*" :=
(autorewrite with tea_list in *).(** * Monoid Instance *)(**********************************************************************)#[export] InstanceMonoid_op_list {A}: Monoid_op (list A) := @app A.#[export] InstanceMonoid_unit_list {A}: Monoid_unit (list A) := nil.#[export, program] InstanceMonoid_list {A}:
@Monoid (list A) (@Monoid_op_list A) (@Monoid_unit_list A).Solve Obligations with
(intros; unfold transparent tcs; auto with datatypes).(** ** Simplification *)(**********************************************************************)
forall (A : Type) (l1l2 : list A), l1 ● l2 = l1 ++ l2
forall (A : Type) (l1l2 : list A), l1 ● l2 = l1 ++ l2
reflexivity.Qed.
forallA : Type, (Ƶ : list A) = []
forallA : Type, (Ƶ : list A) = []
reflexivity.Qed.Ltacsimplify_monoid_list :=
repeatfirst [ rewrite monoid_list_unit_rw
| rewrite monoid_append_rw
].(** * [Functor] Instance *)(**********************************************************************)#[export] InstanceMap_list: Map list :=
funAB => @List.map A B.(** ** Rewriting Laws for <<map>> *)(**********************************************************************)Sectionmap_list_rw.Context
{AB: Type}
(f: A -> B).
A, B: Type f: A -> B
map f [] = []
A, B: Type f: A -> B
map f [] = []
reflexivity.Qed.
A, B: Type f: A -> B
forall (x : A) (xs : list A),
map f (x :: xs) = f x :: map f xs
A, B: Type f: A -> B
forall (x : A) (xs : list A),
map f (x :: xs) = f x :: map f xs
reflexivity.Qed.
A, B: Type f: A -> B a: A
map f [a] = [f a]
A, B: Type f: A -> B a: A
map f [a] = [f a]
reflexivity.Qed.
A, B: Type f: A -> B
foralll1l2 : list A,
map f (l1 ++ l2) = map f l1 ++ map f l2
A, B: Type f: A -> B
foralll1l2 : list A,
map f (l1 ++ l2) = map f l1 ++ map f l2
A, B: Type f: A -> B l1, l2: list A
map f (l1 ++ l2) = map f l1 ++ map f l2
A, B: Type f: A -> B l1, l2: list A
List.map f (l1 ++ l2) = List.map f l1 ++ List.map f l2
now rewrites List.map_app.Qed.Endmap_list_rw.#[export] Hint Rewrite @map_list_nil @map_list_cons
@map_list_one @map_list_app: tea_list.(** ** Functor Laws *)(**********************************************************************)
A: Type
map id = id
A: Type
map id = id
A: Type l: list A
map id l = id l
A: Type
[] = id []
A: Type a: A l: list A IH: map id l = id l
id a :: map id l = id (a :: l)
A: Type a: A l: list A IH: map id l = id l
id a :: map id l = id (a :: l)
nowrewrite IH.Qed.
A, B, C: Type
forall (f : A -> B) (g : B -> C),
map g ∘ map f = map (g ∘ f)
A, B, C: Type
forall (f : A -> B) (g : B -> C),
map g ∘ map f = map (g ∘ f)
A, B, C: Type f: A -> B g: B -> C
map g ∘ map f = map (g ∘ f)
A, B, C: Type f: A -> B g: B -> C
map g ○ map f = map (g ○ f)
A, B, C: Type f: A -> B g: B -> C l: list A
map g (map f l) = map (g ○ f) l
A, B, C: Type f: A -> B g: B -> C
[] = []
A, B, C: Type f: A -> B g: B -> C a: A l: list A IH: map g (map f l) = map (g ○ f) l
g (f a) :: map g (map f l) = g (f a) :: map (g ○ f) l
A, B, C: Type f: A -> B g: B -> C a: A l: list A IH: map g (map f l) = map (g ○ f) l
g (f a) :: map g (map f l) = g (f a) :: map (g ○ f) l
nowrewrite IH.Qed.#[export] InstanceFunctor_list: Functor list :=
{| fun_map_id := @map_id_list;
fun_map_map := @map_map_list;
|}.(** ** <<map>> is a Monoid Homomorphism *)(**********************************************************************)#[export, program] InstanceMonmor_list_map `(f: A -> B):
Monoid_Morphism (list A) (list B) (map f) :=
{| monmor_op := map_list_app f;
|}.(** * Monad Instance (Categorical) *)(**********************************************************************)(** ** Monad Operations *)(**********************************************************************)#[export] InstanceReturn_list: Return list := funAa => cons a nil.#[export] InstanceJoin_list: Join list := @List.concat.(** ** Rewriting Laws for <<join>> *)(**********************************************************************)
forallA : Type, join ([] : list (list A)) = []
forallA : Type, join ([] : list (list A)) = []
reflexivity.Qed.
forall (A : Type) (l : list A) (ll : list (list A)),
join (l :: ll) = l ++ join ll
forall (A : Type) (l : list A) (ll : list (list A)),
join (l :: ll) = l ++ join ll
reflexivity.Qed.
forall (A : Type) (l : list A), join [l] = l
forall (A : Type) (l : list A), join [l] = l
A: Type l: list A
join [l] = l
A: Type l: list A
l ++ [] = l
now List.simpl_list.Qed.
forall (A : Type) (l1l2 : list (list A)),
join (l1 ++ l2) = join l1 ++ join l2
forall (A : Type) (l1l2 : list (list A)),
join (l1 ++ l2) = join l1 ++ join l2
forall (AB : Type) (f : A -> B),
map f ∘ ret = ret ∘ map f
A, B: Type f: A -> B
map f ∘ ret = ret ∘ map f
now ext l.Qed.
Natural (@join list Join_list)
Natural (@join list Join_list)
forall (AB : Type) (f : A -> B),
map f ∘ join = join ∘ map f
A, B: Type f: A -> B
map f ∘ join = join ∘ map f
A, B: Type f: A -> B l: (list ∘ list) A
(map f ∘ join) l = (join ∘ map f) l
A, B: Type f: A -> B l: (list ∘ list) A
map f (join l) = join (map f l)
A, B: Type f: A -> B
map f (join []) = join (map f [])
A, B: Type f: A -> B a: list A l: list (list A) IHl: map f (join l) = join (map f l)
map f (join (a :: l)) = join (map f (a :: l))
A, B: Type f: A -> B
map f (join []) = join (map f [])
reflexivity.
A, B: Type f: A -> B a: list A l: list (list A) IHl: map f (join l) = join (map f l)
map f (join (a :: l)) = join (map f (a :: l))
A, B: Type f: A -> B a: list A l: list (list A) IHl: map f (join l) = join (map f l)
map f a ++ map f (join l) = join (map f (a :: l))
nowrewrite IHl.Qed.
A: Type
join ∘ ret = id
A: Type
join ∘ ret = id
A: Type l: list A
(join ∘ ret) l = id l
A: Type l: list A
join (ret l) = id l
A: Type
join (ret []) = id []
A: Type a: A l: list A
join (ret (a :: l)) = id (a :: l)
A: Type
join (ret []) = id []
reflexivity.
A: Type a: A l: list A
join (ret (a :: l)) = id (a :: l)
A: Type a: A l: list A
a :: l ++ [] = id (a :: l)
now List.simpl_list.Qed.
A: Type
join ∘ map ret = id
A: Type
join ∘ map ret = id
A: Type l: list A
(join ∘ map ret) l = id l
A: Type l: list A
join (map ret l) = id l
A: Type
join (map ret []) = id []
A: Type a: A l: list A IHl: join (map ret l) = id l
join (map ret (a :: l)) = id (a :: l)
A: Type
join (map ret []) = id []
reflexivity.
A: Type a: A l: list A IHl: join (map ret l) = id l
join (map ret (a :: l)) = id (a :: l)
A: Type a: A l: list A IHl: join (map ret l) = id l
ret a ++ join (map ret l) = id (a :: l)
nowrewrite IHl.Qed.
A: Type
join ∘ join = join ∘ map join
A: Type
join ∘ join = join ∘ map join
A: Type l: (list ∘ list) (list A)
(join ∘ join) l = (join ∘ map join) l
A: Type l: (list ∘ list) (list A)
join (join l) = join (map join l)
A: Type
join (join []) = join (map join [])
A: Type a: list (list A) l: list (list (list A)) IHl: join (join l) = join (map join l)
join (join (a :: l)) = join (map join (a :: l))
A: Type
join (join []) = join (map join [])
reflexivity.
A: Type a: list (list A) l: list (list (list A)) IHl: join (join l) = join (map join l)
join (join (a :: l)) = join (map join (a :: l))
A: Type a: list (list A) l: list (list (list A)) IHl: join (join l) = join (map join l)
join a ++ join (join l) = join a ++ join (map join l)
nowrewrite IHl.Qed.#[export] InstanceCategoricalMonad_list:
Categorical.Monad.Monad list :=
{| mon_join_ret := @join_ret_list;
mon_join_map_ret := @join_map_ret_list;
mon_join_join := @join_join_list;
|}.(** ** [join] is a monoid homomorphism *)(** This is a special case of the fact that monoid homomorphisms on free monoids are exact those of of the form <<mapReduce f>> *)#[export] InstanceMonmor_join (A: Type):
Monoid_Morphism (list (list A)) (list A) (join (A := A)) :=
{| monmor_unit := @join_list_nil A;
monmor_op := @join_list_app A;
|}.(** * Traversable Monad Instance (Kleisli) *)(**********************************************************************)(** ** The <<bindt>> Operation *)(**********************************************************************)Fixpointbindt_list (G: Type -> Type)
`{Map G} `{Pure G} `{Mult G}
(A B: Type) (f: A -> G (list B)) (l: list A)
: G (list B) :=
match l with
| nil => pure (@nil B)
| x :: xs =>
pure (@List.app B) <⋆> f x <⋆> bindt_list G A B f xs
end.#[export] InstanceBindt_list: Bindt list list := @bindt_list.
Compat_Map_Bindt list list
Compat_Map_Bindt list list
Map_list = DerivedOperations.Map_Bindt list list
A, B: Type f: A -> B l: list A
Map_list A B f l =
DerivedOperations.Map_Bindt list list A B f l
A, B: Type f: A -> B
Map_list A B f [] =
DerivedOperations.Map_Bindt list list A B f []
A, B: Type f: A -> B a: A rest: list A IHrest: Map_list A B f rest =
DerivedOperations.Map_Bindt list list A B f
rest
Map_list A B f (a :: rest) =
DerivedOperations.Map_Bindt list list A B f
(a :: rest)
A, B: Type f: A -> B
Map_list A B f [] =
DerivedOperations.Map_Bindt list list A B f []
reflexivity.
A, B: Type f: A -> B a: A rest: list A IHrest: Map_list A B f rest =
DerivedOperations.Map_Bindt list list A B f
rest
Map_list A B f (a :: rest) =
DerivedOperations.Map_Bindt list list A B f
(a :: rest)
A, B: Type f: A -> B a: A rest: list A IHrest: Map_list A B f rest =
DerivedOperations.Map_Bindt list list A B f
rest
f a :: Map_list A B f rest =
f a
:: DerivedOperations.Map_Bindt list list A B f rest
nowrewrite IHrest.Qed.(** ** Rewriting Laws for <<bindt>> *)(**********************************************************************)Sectionbindt_rewriting_lemmas.Context
(G: Type -> Type)
`{Applicative G}
(A B: Type).
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type
forallf : A -> G (list B), bindt f [] = pure []
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type
forallf : A -> G (list B), bindt f [] = pure []
reflexivity.Qed.
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type
forall (f : A -> G (list B)) (a : A),
bindt f (ret a) = f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type
forall (f : A -> G (list B)) (a : A),
bindt f (ret a) = f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) a: A
bindt f (ret a) = f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) a: A
pure (app (A:=B)) <⋆> f a <⋆> pure [] = f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) a: A
pure (evalAt []) <⋆> (pure (app (A:=B)) <⋆> f a) = f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) a: A
pure compose <⋆> pure (evalAt []) <⋆>
pure (app (A:=B)) <⋆> f a = f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) a: A
pure (compose (evalAt [])) <⋆> pure (app (A:=B)) <⋆>
f a = f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) a: A
pure (evalAt [] ∘ app (A:=B)) <⋆> f a = f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) a: A
pure (evalAt [] ∘ app (A:=B)) <⋆> f a =
pure id <⋆> f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) a: A l: list B
evalAt [] (app l) = id l ++ []
reflexivity.Qed.
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type
forall (f : A -> G (list B)) (a : A) (l : list A),
bindt f (a :: l) =
pure (app (A:=B)) <⋆> f a <⋆> bindt f l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type
forall (f : A -> G (list B)) (a : A) (l : list A),
bindt f (a :: l) =
pure (app (A:=B)) <⋆> f a <⋆> bindt f l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) a: A l: list A
bindt f (a :: l) =
pure (app (A:=B)) <⋆> f a <⋆> bindt f l
reflexivity.Qed.
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type
forall (f : A -> G (list B)) (l1l2 : list A),
bindt f (l1 ++ l2) =
pure (app (A:=B)) <⋆> bindt f l1 <⋆> bindt f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type
forall (f : A -> G (list B)) (l1l2 : list A),
bindt f (l1 ++ l2) =
pure (app (A:=B)) <⋆> bindt f l1 <⋆> bindt f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) l1, l2: list A
bindt f (l1 ++ l2) =
pure (app (A:=B)) <⋆> bindt f l1 <⋆> bindt f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) l2: list A
bindt f ([] ++ l2) =
pure (app (A:=B)) <⋆> bindt f [] <⋆> bindt f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) a: A l1, l2: list A IHl1: bindt f (l1 ++ l2) =
pure (app (A:=B)) <⋆> bindt f l1 <⋆> bindt f l2
bindt f ((a :: l1) ++ l2) =
pure (app (A:=B)) <⋆> bindt f (a :: l1) <⋆> bindt f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) l2: list A
bindt f ([] ++ l2) =
pure (app (A:=B)) <⋆> bindt f [] <⋆> bindt f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) l2: list A
bindt f l2 =
pure (app (A:=B)) <⋆> pure [] <⋆> bindt f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) l2: list A
bindt f l2 = pure (app []) <⋆> bindt f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) l2: list A
bindt f l2 = bindt f l2
reflexivity.
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) a: A l1, l2: list A IHl1: bindt f (l1 ++ l2) =
pure (app (A:=B)) <⋆> bindt f l1 <⋆> bindt f l2
bindt f ((a :: l1) ++ l2) =
pure (app (A:=B)) <⋆> bindt f (a :: l1) <⋆> bindt f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) a: A l1, l2: list A IHl1: bindt f (l1 ++ l2) =
pure (app (A:=B)) <⋆> bindt f l1 <⋆> bindt f l2
pure (app (A:=B)) <⋆> f a <⋆> bindt f (l1 ++ l2) =
pure (app (A:=B)) <⋆>
(pure (app (A:=B)) <⋆> f a <⋆> bindt f l1) <⋆>
bindt f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) a: A l1, l2: list A IHl1: bindt f (l1 ++ l2) =
pure (app (A:=B)) <⋆> bindt f l1 <⋆> bindt f l2
pure (app (A:=B)) <⋆> f a <⋆>
(pure (app (A:=B)) <⋆> bindt f l1 <⋆> bindt f l2) =
pure (app (A:=B)) <⋆>
(pure (app (A:=B)) <⋆> f a <⋆> bindt f l1) <⋆>
bindt f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) a: A l1, l2: list A IHl1: bindt f (l1 ++ l2) =
pure (app (A:=B)) <⋆> bindt f l1 <⋆> bindt f l2
pure compose <⋆> pure compose <⋆> pure compose <⋆>
pure compose <⋆> pure compose <⋆> pure compose <⋆>
pure compose <⋆> pure (app (A:=B)) <⋆> f a <⋆>
pure (app (A:=B)) <⋆> bindt f l1 <⋆> bindt f l2 =
pure compose <⋆> pure compose <⋆> pure compose <⋆>
pure (app (A:=B)) <⋆> pure (app (A:=B)) <⋆> f a <⋆>
bindt f l1 <⋆> bindt f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) a: A l1, l2: list A IHl1: bindt f (l1 ++ l2) =
pure (app (A:=B)) <⋆> bindt f l1 <⋆> bindt f l2
pure
((compose ∘ compose) compose compose compose compose
(app (A:=B))) <⋆> f a <⋆> pure (app (A:=B)) <⋆>
bindt f l1 <⋆> bindt f l2 =
pure ((compose ∘ compose) (app (A:=B)) (app (A:=B))) <⋆>
f a <⋆> bindt f l1 <⋆> bindt f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) a: A l1, l2: list A IHl1: bindt f (l1 ++ l2) =
pure (app (A:=B)) <⋆> bindt f l1 <⋆> bindt f l2
pure (evalAt (app (A:=B))) <⋆>
(pure
((compose ∘ compose) compose compose compose
compose (app (A:=B))) <⋆> f a) <⋆> bindt f l1 <⋆>
bindt f l2 =
pure ((compose ∘ compose) (app (A:=B)) (app (A:=B))) <⋆>
f a <⋆> bindt f l1 <⋆> bindt f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) a: A l1, l2: list A IHl1: bindt f (l1 ++ l2) =
pure (app (A:=B)) <⋆> bindt f l1 <⋆> bindt f l2
pure compose <⋆> pure (evalAt (app (A:=B))) <⋆>
pure
((compose ∘ compose) compose compose compose compose
(app (A:=B))) <⋆> f a <⋆> bindt f l1 <⋆>
bindt f l2 =
pure ((compose ∘ compose) (app (A:=B)) (app (A:=B))) <⋆>
f a <⋆> bindt f l1 <⋆> bindt f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) a: A l1, l2: list A IHl1: bindt f (l1 ++ l2) =
pure (app (A:=B)) <⋆> bindt f l1 <⋆> bindt f l2
pure
(evalAt (app (A:=B))
∘ (compose ∘ compose) compose compose compose
compose (app (A:=B))) <⋆> f a <⋆> bindt f l1 <⋆>
bindt f l2 =
pure ((compose ∘ compose) (app (A:=B)) (app (A:=B))) <⋆>
f a <⋆> bindt f l1 <⋆> bindt f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) a: A l1, l2: list A IHl1: bindt f (l1 ++ l2) =
pure (app (A:=B)) <⋆> bindt f l1 <⋆> bindt f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) a: A l1, l2: list A IHl1: bindt f (l1 ++ l2) =
pure (app (A:=B)) <⋆> bindt f l1 <⋆> bindt f l2 x, y, z: list B
(evalAt (app (A:=B))
∘ (compose ∘ compose) compose compose compose compose
(app (A:=B))) x y z =
(compose ∘ compose) (app (A:=B)) (app (A:=B)) x y z
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) a: A l1, l2: list A IHl1: bindt f (l1 ++ l2) =
pure (app (A:=B)) <⋆> bindt f l1 <⋆> bindt f l2 x, y, z: list B
evalAt (app (A:=B))
(fun (f : list B -> list B -> list B) (a : list B)
=> app x ○ f a) y z = (x ++ y) ++ z
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G (list B) a: A l1, l2: list A IHl1: bindt f (l1 ++ l2) =
pure (app (A:=B)) <⋆> bindt f l1 <⋆> bindt f l2 x, y, z: list B
x ++ y ++ z = (x ++ y) ++ z
nowrewrite List.app_assoc.Qed.Endbindt_rewriting_lemmas.#[export] Hint Rewrite bindt_list_nil bindt_list_cons
bindt_list_one bindt_list_app:
tea_list.(** ** Traversable Monad Laws *)(**********************************************************************)Sectionbindt_laws.Context
(G: Type -> Type)
`{Applicative G}
`{Applicative G1}
`{Applicative G2}
(A B C: Type).
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type
forallf : A -> G (list B), bindt f ∘ ret = f
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type
forallf : A -> G (list B), bindt f ∘ ret = f
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type f: A -> G (list B)
bindt f ∘ ret = f
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type f: A -> G (list B) a: A
(bindt f ∘ ret) a = f a
apply (bindt_list_one G).Qed.
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type
bindt ret = id
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type
bindt ret = id
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type l: list A
bindt ret l = id l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type
bindt ret [] = id []
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type a: A l: list A IHl: bindt ret l = id l
bindt ret (a :: l) = id (a :: l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type
bindt ret [] = id []
reflexivity.
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type a: A l: list A IHl: bindt ret l = id l
bindt ret (a :: l) = id (a :: l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type a: A l: list A IHl: bindt ret l = id l
a :: bindt ret l = id (a :: l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type a: A l: list A IHl: bindt ret l = id l
a :: id l = id (a :: l)
reflexivity.Qed.
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type
forall (g : B -> G2 (list C)) (f : A -> G1 (list B)),
map (bindt g) ∘ bindt f = bindt (g ⋆6 f)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type
forall (g : B -> G2 (list C)) (f : A -> G1 (list B)),
map (bindt g) ∘ bindt f = bindt (g ⋆6 f)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B)
map (bindt g) ∘ bindt f = bindt (g ⋆6 f)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) l: list A
(map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B)
(map (bindt g) ∘ bindt f) [] = bindt (g ⋆6 f) []
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
(map (bindt g) ∘ bindt f) (a :: l) =
bindt (g ⋆6 f) (a :: l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B)
(map (bindt g) ∘ bindt f) [] = bindt (g ⋆6 f) []
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B)
map (bindt g) (pure []) = pure []
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B)
pure (bindt g []) = pure []
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B)
pure (pure []) = pure []
reflexivity.
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
(map (bindt g) ∘ bindt f) (a :: l) =
bindt (g ⋆6 f) (a :: l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
map (bindt g) (bindt f (a :: l)) =
bindt (g ⋆6 f) (a :: l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
map (bindt g)
(pure (app (A:=B)) <⋆> f a <⋆> bindt f l) =
bindt (g ⋆6 f) (a :: l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure (bindt g) <⋆>
(pure (app (A:=B)) <⋆> f a <⋆> bindt f l) =
bindt (g ⋆6 f) (a :: l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure compose <⋆> pure compose <⋆> pure compose <⋆>
pure (bindt g) <⋆> pure (app (A:=B)) <⋆> f a <⋆>
bindt f l = bindt (g ⋆6 f) (a :: l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure ((compose ∘ compose) (bindt g) (app (A:=B))) <⋆>
f a <⋆> bindt f l = bindt (g ⋆6 f) (a :: l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure ((compose ∘ compose) (bindt g) (app (A:=B))) <⋆>
f a <⋆> bindt f l =
pure (app (A:=C)) <⋆> (g ⋆6 f) a <⋆> bindt (g ⋆6 f) l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure ((compose ∘ compose) (bindt g) (app (A:=B))) <⋆>
f a <⋆> bindt f l =
pure (app (A:=C)) <⋆> (g ⋆6 f) a <⋆>
(map (bindt g) ∘ bindt f) l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure ((compose ∘ compose) (bindt g) (app (A:=B))) <⋆>
f a <⋆> bindt f l =
pure (app (A:=C)) <⋆> (g ⋆6 f) a <⋆>
map (bindt g) (bindt f l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure ((compose ∘ compose) (bindt g) (app (A:=B))) <⋆>
f a <⋆> bindt f l =
pure (ap G2) <⋆>
(pure (ap G2) <⋆> pure (app (A:=C)) <⋆> (g ⋆6 f) a) <⋆>
map (bindt g) (bindt f l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure ((compose ∘ compose) (bindt g) (app (A:=B))) <⋆>
f a <⋆> bindt f l =
pure (ap G2) <⋆>
(pure (ap G2) <⋆> pure (pure (app (A:=C))) <⋆>
(g ⋆6 f) a) <⋆> map (bindt g) (bindt f l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure ((compose ∘ compose) (bindt g) (app (A:=B))) <⋆>
f a <⋆> bindt f l =
pure (ap G2) <⋆>
(pure (ap G2) <⋆> pure (pure (app (A:=C))) <⋆>
(g ⋆6 f) a) <⋆> (pure (bindt g) <⋆> bindt f l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure ((compose ∘ compose) (bindt g) (app (A:=B))) <⋆>
f a <⋆> bindt f l =
pure compose <⋆>
(pure (ap G2) <⋆>
(pure (ap G2) <⋆> pure (pure (app (A:=C))) <⋆>
(g ⋆6 f) a)) <⋆> pure (bindt g) <⋆> bindt f l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure ((compose ∘ compose) (bindt g) (app (A:=B))) <⋆>
f a <⋆> bindt f l =
pure compose <⋆> pure compose <⋆> pure (ap G2) <⋆>
(pure (ap G2) <⋆> pure (pure (app (A:=C))) <⋆>
(g ⋆6 f) a) <⋆> pure (bindt g) <⋆> bindt f l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure ((compose ∘ compose) (bindt g) (app (A:=B))) <⋆>
f a <⋆> bindt f l =
pure compose <⋆>
(pure compose <⋆> pure compose <⋆> pure (ap G2)) <⋆>
(pure (ap G2) <⋆> pure (pure (app (A:=C)))) <⋆>
(g ⋆6 f) a <⋆> pure (bindt g) <⋆> bindt f l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure ((compose ∘ compose) (bindt g) (app (A:=B))) <⋆>
f a <⋆> bindt f l =
pure compose <⋆>
(pure compose <⋆>
(pure compose <⋆> pure compose <⋆> pure (ap G2))) <⋆>
pure (ap G2) <⋆> pure (pure (app (A:=C))) <⋆>
(g ⋆6 f) a <⋆> pure (bindt g) <⋆> bindt f l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure ((compose ∘ compose) (bindt g) (app (A:=B))) <⋆>
f a <⋆> bindt f l =
pure
((compose (compose ∘ ap G2) ∘ ap G2)
(pure (app (A:=C)))) <⋆> (g ⋆6 f) a <⋆>
pure (bindt g) <⋆> bindt f l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure ((compose ∘ compose) (bindt g) (app (A:=B))) <⋆>
f a <⋆> bindt f l =
pure
((compose (compose ∘ ap G2) ∘ ap G2)
(pure (app (A:=C)))) <⋆> (map (bindt g) ∘ f) a <⋆>
pure (bindt g) <⋆> bindt f l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure ((compose ∘ compose) (bindt g) (app (A:=B))) <⋆>
f a <⋆> bindt f l =
pure
((compose (compose ∘ ap G2) ∘ ap G2)
(pure (app (A:=C)))) <⋆> map (bindt g) (f a) <⋆>
pure (bindt g) <⋆> bindt f l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure ((compose ∘ compose) (bindt g) (app (A:=B))) <⋆>
f a <⋆> bindt f l =
pure
((compose (compose ∘ ap G2) ∘ ap G2)
(pure (app (A:=C)))) <⋆> (pure (bindt g) <⋆> f a) <⋆>
pure (bindt g) <⋆> bindt f l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure ((compose ∘ compose) (bindt g) (app (A:=B))) <⋆>
f a <⋆> bindt f l =
pure compose <⋆>
pure
((compose (compose ∘ ap G2) ∘ ap G2)
(pure (app (A:=C)))) <⋆> pure (bindt g) <⋆> f a <⋆>
pure (bindt g) <⋆> bindt f l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure ((compose ∘ compose) (bindt g) (app (A:=B))) <⋆>
f a <⋆> bindt f l =
pure
((compose (compose ∘ ap G2) ∘ ap G2)
(pure (app (A:=C))) ∘ bindt g) <⋆> f a <⋆>
pure (bindt g) <⋆> bindt f l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure ((compose ∘ compose) (bindt g) (app (A:=B))) <⋆>
f a <⋆> bindt f l =
pure (evalAt (bindt g)) <⋆>
(pure
((compose (compose ∘ ap G2) ∘ ap G2)
(pure (app (A:=C))) ∘ bindt g) <⋆> f a) <⋆>
bindt f l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure ((compose ∘ compose) (bindt g) (app (A:=B))) <⋆>
f a <⋆> bindt f l =
pure compose <⋆> pure (evalAt (bindt g)) <⋆>
pure
((compose (compose ∘ ap G2) ∘ ap G2)
(pure (app (A:=C))) ∘ bindt g) <⋆> f a <⋆>
bindt f l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure ((compose ∘ compose) (bindt g) (app (A:=B))) <⋆>
f a <⋆> bindt f l =
pure
(evalAt (bindt g)
∘ ((compose (compose ∘ ap G2) ∘ ap G2)
(pure (app (A:=C))) ∘ bindt g)) <⋆> f a <⋆>
bindt f l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure ((compose ∘ compose) (bindt g) (app (A:=B))) <⋆>
f a =
pure
(evalAt (bindt g)
∘ ((compose (compose ∘ ap G2) ∘ ap G2)
(pure (app (A:=C))) ∘ bindt g)) <⋆> f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
pure ((compose ∘ compose) (bindt g) (app (A:=B))) =
pure
(evalAt (bindt g)
∘ ((compose (compose ∘ ap G2) ∘ ap G2)
(pure (app (A:=C))) ∘ bindt g))
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l l1, l2: list B
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l l1, l2: list B
bindt g (l1 ++ l2) =
evalAt (bindt g)
(funf : list B -> G2 (list C) =>
ap G2 (pure (app (A:=C)) <⋆> bindt g l1) ○ f) l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G G1: Type -> Type Map_G0: Map G1 Pure_G0: Pure G1 Mult_G0: Mult G1 H0: Applicative G1 G2: Type -> Type Map_G1: Map G2 Pure_G1: Pure G2 Mult_G1: Mult G2 H1: Applicative G2 A, B, C: Type g: B -> G2 (list C) f: A -> G1 (list B) a: A l: list A IHl: (map (bindt g) ∘ bindt f) l = bindt (g ⋆6 f) l l1, l2: list B
pure (app (A:=C)) <⋆> bindt g l1 <⋆> bindt g l2 =
evalAt (bindt g)
(funf : list B -> G2 (list C) =>
ap G2 (pure (app (A:=C)) <⋆> bindt g l1) ○ f) l2
reflexivity.Qed.Endbindt_laws.
forall (G1G2 : Type -> Type) (H : Map G1)
(H0 : Mult G1) (H1 : Pure G1) (H2 : Map G2)
(H3 : Mult G2) (H4 : Pure G2)
(ϕ : forallA : Type, G1 A -> G2 A),
ApplicativeMorphism G1 G2 ϕ ->
forall (AB : Type) (f : A -> G1 (list B)),
ϕ (list B) ∘ bindt f = bindt (ϕ (list B) ∘ f)
forall (G1G2 : Type -> Type) (H : Map G1)
(H0 : Mult G1) (H1 : Pure G1) (H2 : Map G2)
(H3 : Mult G2) (H4 : Pure G2)
(ϕ : forallA : Type, G1 A -> G2 A),
ApplicativeMorphism G1 G2 ϕ ->
forall (AB : Type) (f : A -> G1 (list B)),
ϕ (list B) ∘ bindt f = bindt (ϕ (list B) ∘ f)
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A morph: ApplicativeMorphism G1 G2 ϕ A, B: Type f: A -> G1 (list B)
ϕ (list B) ∘ bindt f = bindt (ϕ (list B) ∘ f)
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A morph: ApplicativeMorphism G1 G2 ϕ A, B: Type f: A -> G1 (list B)
ϕ (list B) ○ bindt f = bindt (ϕ (list B) ○ f)
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A morph: ApplicativeMorphism G1 G2 ϕ A, B: Type f: A -> G1 (list B) l: list A
ϕ (list B) (bindt f l) = bindt (ϕ (list B) ○ f) l
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A morph: ApplicativeMorphism G1 G2 ϕ A, B: Type f: A -> G1 (list B)
ϕ (list B) (bindt f []) = bindt (ϕ (list B) ○ f) []
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A morph: ApplicativeMorphism G1 G2 ϕ A, B: Type f: A -> G1 (list B) a: A l: list A IHl: ϕ (list B) (bindt f l) =
bindt (ϕ (list B) ○ f) l
ϕ (list B) (bindt f (a :: l)) =
bindt (ϕ (list B) ○ f) (a :: l)
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A morph: ApplicativeMorphism G1 G2 ϕ A, B: Type f: A -> G1 (list B)
ϕ (list B) (bindt f []) = bindt (ϕ (list B) ○ f) []
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A morph: ApplicativeMorphism G1 G2 ϕ A, B: Type f: A -> G1 (list B)
ϕ (list B) (pure []) = pure []
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A morph: ApplicativeMorphism G1 G2 ϕ A, B: Type f: A -> G1 (list B)
pure [] = pure []
reflexivity.
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A morph: ApplicativeMorphism G1 G2 ϕ A, B: Type f: A -> G1 (list B) a: A l: list A IHl: ϕ (list B) (bindt f l) =
bindt (ϕ (list B) ○ f) l
ϕ (list B) (bindt f (a :: l)) =
bindt (ϕ (list B) ○ f) (a :: l)
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A morph: ApplicativeMorphism G1 G2 ϕ A, B: Type f: A -> G1 (list B) a: A l: list A IHl: ϕ (list B) (bindt f l) =
bindt (ϕ (list B) ○ f) l
ϕ (list B) (pure (app (A:=B)) <⋆> f a <⋆> bindt f l) =
pure (app (A:=B)) <⋆> ϕ (list B) (f a) <⋆>
bindt (ϕ (list B) ○ f) l
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A morph: ApplicativeMorphism G1 G2 ϕ A, B: Type f: A -> G1 (list B) a: A l: list A IHl: ϕ (list B) (bindt f l) =
bindt (ϕ (list B) ○ f) l
ϕ (list B -> list B) (pure (app (A:=B)) <⋆> f a) <⋆>
ϕ (list B) (bindt f l) =
pure (app (A:=B)) <⋆> ϕ (list B) (f a) <⋆>
bindt (ϕ (list B) ○ f) l
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A morph: ApplicativeMorphism G1 G2 ϕ A, B: Type f: A -> G1 (list B) a: A l: list A IHl: ϕ (list B) (bindt f l) =
bindt (ϕ (list B) ○ f) l
ϕ (list B -> list B -> list B) (pure (app (A:=B))) <⋆>
ϕ (list B) (f a) <⋆> ϕ (list B) (bindt f l) =
pure (app (A:=B)) <⋆> ϕ (list B) (f a) <⋆>
bindt (ϕ (list B) ○ f) l
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A morph: ApplicativeMorphism G1 G2 ϕ A, B: Type f: A -> G1 (list B) a: A l: list A IHl: ϕ (list B) (bindt f l) =
bindt (ϕ (list B) ○ f) l
pure (app (A:=B)) <⋆> ϕ (list B) (f a) <⋆>
ϕ (list B) (bindt f l) =
pure (app (A:=B)) <⋆> ϕ (list B) (f a) <⋆>
bindt (ϕ (list B) ○ f) l
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A morph: ApplicativeMorphism G1 G2 ϕ A, B: Type f: A -> G1 (list B) a: A l: list A IHl: ϕ (list B) (bindt f l) =
bindt (ϕ (list B) ○ f) l
pure (app (A:=B)) <⋆> ϕ (list B) (f a) <⋆>
bindt (ϕ (list B) ○ f) l =
pure (app (A:=B)) <⋆> ϕ (list B) (f a) <⋆>
bindt (ϕ (list B) ○ f) l
reflexivity.Qed.(** ** Typeclass Instance *)(**********************************************************************)#[export] InstanceTraversableRightPreModule_list:
TraversableRightPreModule list list :=
{| ktm_bindt1 := list_bindt1;
ktm_bindt2 := @list_bindt2;
ktm_morph := @list_morph;
|}.#[export] InstanceTraversableMonad_list:
TraversableMonad list :=
{| ktm_bindt0 := list_bindt0;
|}.#[export] InstanceTraversableRightModule_list:
TraversableRightModule list list :=
DerivedInstances.TraversableRightModule_TraversableMonad.(** * Traversable Functor Instance (Kleisli) *)(**********************************************************************)Fixpointtraverse_list (G: Type -> Type)
`{Map G} `{Pure G} `{Mult G}
(A B: Type) (f: A -> G B) (l: list A)
: G (list B) :=
match l with
| nil => pure (@nil B)
| x :: xs =>
pure (@List.cons B) <⋆> f x <⋆> (traverse_list G A B f xs)
end.#[export] InstanceTraverse_list: Traverse list := @traverse_list.
Compat_Traverse_Bindt list list
Compat_Traverse_Bindt list list
forall (G : Type -> Type) (Map_G : Map G)
(Pure_G : Pure G) (Mult_G : Mult G),
Applicative G ->
Traverse_list G Map_G Pure_G Mult_G =
DerivedOperations.Traverse_Bindt list list G Map_G
Pure_G Mult_G
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G Applicative0: Applicative G
Traverse_list G Map_G Pure_G Mult_G =
DerivedOperations.Traverse_Bindt list list G Map_G
Pure_G Mult_G
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G Applicative0: Applicative G A, B: Type f: A -> G B l: list A
Traverse_list G Map_G Pure_G Mult_G A B f l =
DerivedOperations.Traverse_Bindt list list G Map_G
Pure_G Mult_G A B f l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G Applicative0: Applicative G A, B: Type f: A -> G B l: list A
Traverse_list G Map_G Pure_G Mult_G A B f l =
bindt (map ret ∘ f) l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G Applicative0: Applicative G A, B: Type f: A -> G B
Traverse_list G Map_G Pure_G Mult_G A B f [] =
bindt (map ret ∘ f) []
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G Applicative0: Applicative G A, B: Type f: A -> G B a: A rest: list A IHrest: Traverse_list G Map_G Pure_G Mult_G A B f
rest = bindt (map ret ∘ f) rest
Traverse_list G Map_G Pure_G Mult_G A B f (a :: rest) =
bindt (map ret ∘ f) (a :: rest)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G Applicative0: Applicative G A, B: Type f: A -> G B
Traverse_list G Map_G Pure_G Mult_G A B f [] =
bindt (map ret ∘ f) []
reflexivity.
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G Applicative0: Applicative G A, B: Type f: A -> G B a: A rest: list A IHrest: Traverse_list G Map_G Pure_G Mult_G A B f
rest = bindt (map ret ∘ f) rest
Traverse_list G Map_G Pure_G Mult_G A B f (a :: rest) =
bindt (map ret ∘ f) (a :: rest)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G Applicative0: Applicative G A, B: Type f: A -> G B a: A rest: list A IHrest: Traverse_list G Map_G Pure_G Mult_G A B f
rest = bindt (map ret ∘ f) rest
pure cons <⋆> f a <⋆>
Traverse_list G Map_G Pure_G Mult_G A B f rest =
pure (app (A:=B)) <⋆> (map ret ∘ f) a <⋆>
bindt (map ret ∘ f) rest
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G Applicative0: Applicative G A, B: Type f: A -> G B a: A rest: list A IHrest: Traverse_list G Map_G Pure_G Mult_G A B f
rest = bindt (map ret ∘ f) rest
pure cons <⋆> f a <⋆> bindt (map ret ∘ f) rest =
pure (app (A:=B)) <⋆> (map ret ∘ f) a <⋆>
bindt (map ret ∘ f) rest
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G Applicative0: Applicative G A, B: Type f: A -> G B a: A rest: list A IHrest: Traverse_list G Map_G Pure_G Mult_G A B f
rest = bindt (map ret ∘ f) rest
pure cons <⋆> f a <⋆> bindt (map ret ∘ f) rest =
pure (app (A:=B)) <⋆> map ret (f a) <⋆>
bindt (map ret ∘ f) rest
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G Applicative0: Applicative G A, B: Type f: A -> G B a: A rest: list A IHrest: Traverse_list G Map_G Pure_G Mult_G A B f
rest = bindt (map ret ∘ f) rest
pure cons <⋆> f a <⋆> bindt (map ret ∘ f) rest =
map (app (A:=B) ∘ ret) (f a) <⋆>
bindt (map ret ∘ f) rest
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G Applicative0: Applicative G A, B: Type f: A -> G B a: A rest: list A IHrest: Traverse_list G Map_G Pure_G Mult_G A B f
rest = bindt (map ret ∘ f) rest
pure cons <⋆> f a <⋆> bindt (map ret ∘ f) rest =
pure (app (A:=B) ∘ ret) <⋆> f a <⋆>
bindt (map ret ∘ f) rest
reflexivity.Qed.#[export] InstanceCompat_Map_Traverse_list:
Compat_Map_Traverse list :=
Compat_Map_Traverse_Bindt.(** ** Rewriting Laws for <<traverse>> *)(**********************************************************************)Sectiontraverse_rewriting_lemmas.Context
(G: Type -> Type)
`{Applicative G}
(A B: Type).
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type
forallf : A -> G B, traverse f [] = pure []
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type
forallf : A -> G B, traverse f [] = pure []
reflexivity.Qed.
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type
forall (f : A -> G B) (a : A),
traverse f (ret a) = map ret (f a)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type
forall (f : A -> G B) (a : A),
traverse f (ret a) = map ret (f a)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B a: A
traverse f (ret a) = map ret (f a)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B a: A
pure cons <⋆> f a <⋆> pure [] = map ret (f a)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B a: A
pure (evalAt []) <⋆> (pure cons <⋆> f a) =
map ret (f a)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B a: A
pure (evalAt [] ∘ cons) <⋆> f a = map ret (f a)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B a: A
map (evalAt [] ∘ cons) (f a) = map ret (f a)
reflexivity.Qed.
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type
forall (f : A -> G B) (a : A) (l : list A),
traverse f (a :: l) =
pure cons <⋆> f a <⋆> traverse f l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type
forall (f : A -> G B) (a : A) (l : list A),
traverse f (a :: l) =
pure cons <⋆> f a <⋆> traverse f l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B a: A l: list A
traverse f (a :: l) =
pure cons <⋆> f a <⋆> traverse f l
reflexivity.Qed.
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type
forall (f : A -> G B) (l1l2 : list A),
traverse f (l1 ++ l2) =
pure (app (A:=B)) <⋆> traverse f l1 <⋆> traverse f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type
forall (f : A -> G B) (l1l2 : list A),
traverse f (l1 ++ l2) =
pure (app (A:=B)) <⋆> traverse f l1 <⋆> traverse f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B l1, l2: list A
traverse f (l1 ++ l2) =
pure (app (A:=B)) <⋆> traverse f l1 <⋆> traverse f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B l2: list A
traverse f ([] ++ l2) =
pure (app (A:=B)) <⋆> traverse f [] <⋆> traverse f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B a: A l1, l2: list A IHl1: traverse f (l1 ++ l2) =
pure (app (A:=B)) <⋆> traverse f l1 <⋆>
traverse f l2
traverse f ((a :: l1) ++ l2) =
pure (app (A:=B)) <⋆> traverse f (a :: l1) <⋆>
traverse f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B l2: list A
traverse f ([] ++ l2) =
pure (app (A:=B)) <⋆> traverse f [] <⋆> traverse f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B l2: list A
traverse f l2 =
pure (app (A:=B)) <⋆> pure [] <⋆> traverse f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B l2: list A
traverse f l2 = pure (app []) <⋆> traverse f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B l2: list A
traverse f l2 = traverse f l2
reflexivity.
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B a: A l1, l2: list A IHl1: traverse f (l1 ++ l2) =
pure (app (A:=B)) <⋆> traverse f l1 <⋆>
traverse f l2
traverse f ((a :: l1) ++ l2) =
pure (app (A:=B)) <⋆> traverse f (a :: l1) <⋆>
traverse f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B a: A l1, l2: list A IHl1: traverse f (l1 ++ l2) =
pure (app (A:=B)) <⋆> traverse f l1 <⋆>
traverse f l2
pure cons <⋆> f a <⋆> traverse f (l1 ++ l2) =
pure (app (A:=B)) <⋆>
(pure cons <⋆> f a <⋆> traverse f l1) <⋆>
traverse f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B a: A l1, l2: list A IHl1: traverse f (l1 ++ l2) =
pure (app (A:=B)) <⋆> traverse f l1 <⋆>
traverse f l2
pure cons <⋆> f a <⋆>
(pure (app (A:=B)) <⋆> traverse f l1 <⋆> traverse f l2) =
pure (app (A:=B)) <⋆>
(pure cons <⋆> f a <⋆> traverse f l1) <⋆>
traverse f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B a: A l1, l2: list A IHl1: traverse f (l1 ++ l2) =
pure (app (A:=B)) <⋆> traverse f l1 <⋆>
traverse f l2
pure compose <⋆> pure compose <⋆> pure compose <⋆>
pure compose <⋆> pure compose <⋆> pure compose <⋆>
pure compose <⋆> pure cons <⋆> f a <⋆>
pure (app (A:=B)) <⋆> traverse f l1 <⋆> traverse f l2 =
pure compose <⋆> pure compose <⋆> pure compose <⋆>
pure (app (A:=B)) <⋆> pure cons <⋆> f a <⋆>
traverse f l1 <⋆> traverse f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B a: A l1, l2: list A IHl1: traverse f (l1 ++ l2) =
pure (app (A:=B)) <⋆> traverse f l1 <⋆>
traverse f l2
pure
((compose ∘ compose) compose compose compose compose
cons) <⋆> f a <⋆> pure (app (A:=B)) <⋆>
traverse f l1 <⋆> traverse f l2 =
pure ((compose ∘ compose) (app (A:=B)) cons) <⋆> f a <⋆>
traverse f l1 <⋆> traverse f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B a: A l1, l2: list A IHl1: traverse f (l1 ++ l2) =
pure (app (A:=B)) <⋆> traverse f l1 <⋆>
traverse f l2
pure (evalAt (app (A:=B))) <⋆>
(pure
((compose ∘ compose) compose compose compose
compose cons) <⋆> f a) <⋆> traverse f l1 <⋆>
traverse f l2 =
pure ((compose ∘ compose) (app (A:=B)) cons) <⋆> f a <⋆>
traverse f l1 <⋆> traverse f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B a: A l1, l2: list A IHl1: traverse f (l1 ++ l2) =
pure (app (A:=B)) <⋆> traverse f l1 <⋆>
traverse f l2
pure compose <⋆> pure (evalAt (app (A:=B))) <⋆>
pure
((compose ∘ compose) compose compose compose compose
cons) <⋆> f a <⋆> traverse f l1 <⋆> traverse f l2 =
pure ((compose ∘ compose) (app (A:=B)) cons) <⋆> f a <⋆>
traverse f l1 <⋆> traverse f l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B a: A l1, l2: list A IHl1: traverse f (l1 ++ l2) =
pure (app (A:=B)) <⋆> traverse f l1 <⋆>
traverse f l2
pure
(evalAt (app (A:=B))
∘ (compose ∘ compose) compose compose compose
compose cons) <⋆> f a <⋆> traverse f l1 <⋆>
traverse f l2 =
pure ((compose ∘ compose) (app (A:=B)) cons) <⋆> f a <⋆>
traverse f l1 <⋆> traverse f l2
reflexivity.Qed.Definitionsnoc {A: Type} (l: list A) (a: A) := l ++ [a].
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type
forall (f : A -> G B) (l : list A) (a : A),
traverse f (l ++ [a]) =
pure snoc <⋆> traverse f l <⋆> f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type
forall (f : A -> G B) (l : list A) (a : A),
traverse f (l ++ [a]) =
pure snoc <⋆> traverse f l <⋆> f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B l: list A a: A
traverse f (l ++ [a]) =
pure snoc <⋆> traverse f l <⋆> f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B l: list A a: A
pure (app (A:=B)) <⋆> traverse f l <⋆> traverse f [a] =
pure snoc <⋆> traverse f l <⋆> f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B l: list A a: A
pure (app (A:=B)) <⋆> traverse f l <⋆>
(pure cons <⋆> f a <⋆> pure []) =
pure snoc <⋆> traverse f l <⋆> f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B l: list A a: A
pure compose <⋆> pure compose <⋆> pure compose <⋆>
pure compose <⋆> pure compose <⋆> pure compose <⋆>
pure compose <⋆> pure (app (A:=B)) <⋆> traverse f l <⋆>
pure cons <⋆> f a <⋆> pure [] =
pure snoc <⋆> traverse f l <⋆> f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B l: list A a: A
pure
((compose ∘ compose) compose compose compose compose
(app (A:=B))) <⋆> traverse f l <⋆> pure cons <⋆>
f a <⋆> pure [] = pure snoc <⋆> traverse f l <⋆> f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B l: list A a: A
pure (evalAt []) <⋆>
(pure
((compose ∘ compose) compose compose compose
compose (app (A:=B))) <⋆> traverse f l <⋆>
pure cons <⋆> f a) =
pure snoc <⋆> traverse f l <⋆> f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B l: list A a: A
pure compose <⋆> pure compose <⋆> pure compose <⋆>
pure compose <⋆> pure compose <⋆> pure compose <⋆>
pure compose <⋆> pure compose <⋆> pure (evalAt []) <⋆>
pure
((compose ∘ compose) compose compose compose compose
(app (A:=B))) <⋆> traverse f l <⋆> pure cons <⋆>
f a = pure snoc <⋆> traverse f l <⋆> f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B l: list A a: A
pure
((compose ∘ compose) compose compose compose compose
compose (evalAt [])
((compose ∘ compose) compose compose compose
compose (app (A:=B)))) <⋆> traverse f l <⋆>
pure cons <⋆> f a = pure snoc <⋆> traverse f l <⋆> f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B l: list A a: A
pure (evalAt cons) <⋆>
(pure
((compose ∘ compose) compose compose compose
compose compose (evalAt [])
((compose ∘ compose) compose compose compose
compose (app (A:=B)))) <⋆> traverse f l) <⋆>
f a = pure snoc <⋆> traverse f l <⋆> f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B l: list A a: A
pure compose <⋆> pure (evalAt cons) <⋆>
pure
((compose ∘ compose) compose compose compose compose
compose (evalAt [])
((compose ∘ compose) compose compose compose
compose (app (A:=B)))) <⋆> traverse f l <⋆>
f a = pure snoc <⋆> traverse f l <⋆> f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B l: list A a: A
pure
(evalAt cons
∘ (compose ∘ compose) compose compose compose
compose compose (evalAt [])
((compose ∘ compose) compose compose compose
compose (app (A:=B)))) <⋆> traverse f l <⋆>
f a = pure snoc <⋆> traverse f l <⋆> f a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> G B l: list A a: A
pure
(funa : list B =>
evalAt cons
(fun (a0 : B -> list B -> list B) (a1 : B) =>
evalAt [] (app a ○ a0 a1))) <⋆> traverse f l <⋆>
f a = pure snoc <⋆> traverse f l <⋆> f a
reflexivity.Qed.Endtraverse_rewriting_lemmas.#[export] Hint Rewrite traverse_list_nil traverse_list_cons
traverse_list_one traverse_list_snoc traverse_list_app:
tea_list.#[export] InstanceTraversableFunctor_list:
TraversableFunctor list :=
DerivedInstances.TraversableFunctor_TraversableMonad.(** * Monad Instance (Kleisli) *)(**********************************************************************)Fixpointbind_list (AB: Type) (f: A -> list B) (l: list A): list B :=
match l with
| nil => @nil B
| x :: xs =>
f x ● bind_list A B f xs
end.#[export] InstanceBind_list: Bind list list := @bind_list.
Compat_Bind_Bindt list list
Compat_Bind_Bindt list list
Bind_list = DerivedOperations.Bind_Bindt list list
A, B: Type f: A -> list B l: list A
Bind_list A B f l =
DerivedOperations.Bind_Bindt list list A B f l
A, B: Type f: A -> list B
Bind_list A B f [] =
DerivedOperations.Bind_Bindt list list A B f []
A, B: Type f: A -> list B a: A rest: list A IHrest: Bind_list A B f rest =
DerivedOperations.Bind_Bindt list list A B f
rest
Bind_list A B f (a :: rest) =
DerivedOperations.Bind_Bindt list list A B f
(a :: rest)
A, B: Type f: A -> list B
Bind_list A B f [] =
DerivedOperations.Bind_Bindt list list A B f []
reflexivity.
A, B: Type f: A -> list B a: A rest: list A IHrest: Bind_list A B f rest =
DerivedOperations.Bind_Bindt list list A B f
rest
Bind_list A B f (a :: rest) =
DerivedOperations.Bind_Bindt list list A B f
(a :: rest)
A, B: Type f: A -> list B a: A rest: list A IHrest: Bind_list A B f rest =
DerivedOperations.Bind_Bindt list list A B f
rest
f a ● Bind_list A B f rest =
pure (app (A:=B)) (f a)
(DerivedOperations.Bind_Bindt list list A B f rest)
nowrewrite IHrest.Qed.#[export] InstanceCompat_Map_Bind_list:
Compat_Map_Bind list list
:= ltac:(typeclasses eauto).(** ** Rewriting Laws for <<bind>> *)(**********************************************************************)Sectionbind_rewriting_lemmas.Context
(AB: Type).
A, B: Type
forallf : A -> list B, bind f [] = []
A, B: Type
forallf : A -> list B, bind f [] = []
reflexivity.Qed.
A, B: Type
forall (f : A -> list B) (a : A), bind f (ret a) = f a
A, B: Type
forall (f : A -> list B) (a : A), bind f (ret a) = f a
A, B: Type f: A -> list B a: A
bind f (ret a) = f a
A, B: Type f: A -> list B a: A
f a ● [] = f a
A, B: Type f: A -> list B a: A
f a ● (Ƶ : list B) = f a
now simpl_monoid.Qed.
A, B: Type
forall (f : A -> list B) (a : A) (l : list A),
bind f (a :: l) = f a ++ bind f l
A, B: Type
forall (f : A -> list B) (a : A) (l : list A),
bind f (a :: l) = f a ++ bind f l
reflexivity.Qed.
A, B: Type
forall (f : A -> list B) (l1l2 : list A),
bind f (l1 ++ l2) = bind f l1 ++ bind f l2
A, B: Type
forall (f : A -> list B) (l1l2 : list A),
bind f (l1 ++ l2) = bind f l1 ++ bind f l2
A, B: Type f: A -> list B l1, l2: list A
bind f (l1 ++ l2) = bind f l1 ++ bind f l2
A, B: Type f: A -> list B l2: list A
bind f ([] ++ l2) = bind f [] ++ bind f l2
A, B: Type f: A -> list B a: A l1, l2: list A IHl1: bind f (l1 ++ l2) = bind f l1 ++ bind f l2
bind f ((a :: l1) ++ l2) =
bind f (a :: l1) ++ bind f l2
A, B: Type f: A -> list B l2: list A
bind f ([] ++ l2) = bind f [] ++ bind f l2
A, B: Type f: A -> list B l2: list A
bind f l2 = bind f l2
reflexivity.
A, B: Type f: A -> list B a: A l1, l2: list A IHl1: bind f (l1 ++ l2) = bind f l1 ++ bind f l2
bind f ((a :: l1) ++ l2) =
bind f (a :: l1) ++ bind f l2
A, B: Type f: A -> list B a: A l1, l2: list A IHl1: bind f (l1 ++ l2) = bind f l1 ++ bind f l2
f a ● bind f (l1 ++ l2) =
(f a ● bind f l1) ++ bind f l2
A, B: Type f: A -> list B a: A l1, l2: list A IHl1: bind f (l1 ++ l2) = bind f l1 ++ bind f l2
f a ● (bind f l1 ++ bind f l2) =
(f a ● bind f l1) ++ bind f l2
A, B: Type f: A -> list B a: A l1, l2: list A IHl1: bind f (l1 ++ l2) = bind f l1 ++ bind f l2
f a ++ bind f l1 ++ bind f l2 =
(f a ++ bind f l1) ++ bind f l2
A, B: Type f: A -> list B a: A l1, l2: list A IHl1: bind f (l1 ++ l2) = bind f l1 ++ bind f l2
(f a ++ bind f l1) ++ bind f l2 =
(f a ++ bind f l1) ++ bind f l2
reflexivity.Qed.Endbind_rewriting_lemmas.#[export] Hint Rewrite bind_list_nil bind_list_cons
bind_list_one bind_list_app: tea_list.(** ** [bind] is a Monoid Homomorphism *)(**********************************************************************)
A, B: Type f: A -> list B
Monoid_Morphism (list A) (list B) (bind f)
A, B: Type f: A -> list B
Monoid_Morphism (list A) (list B) (bind f)
A, B: Type f: A -> list B
bind f Ƶ = Ƶ
A, B: Type f: A -> list B
foralla1a2 : list A,
bind f (a1 ● a2) = bind f a1 ● bind f a2
A, B: Type f: A -> list B
bind f Ƶ = Ƶ
reflexivity.
A, B: Type f: A -> list B
foralla1a2 : list A,
bind f (a1 ● a2) = bind f a1 ● bind f a2
A, B: Type f: A -> list B a1, a2: list A
bind f (a1 ● a2) = bind f a1 ● bind f a2
A, B: Type f: A -> list B a2: list A
bind f ([] ● a2) = bind f [] ● bind f a2
A, B: Type f: A -> list B a: A a1, a2: list A IHa1: bind f (a1 ● a2) = bind f a1 ● bind f a2
bind f ((a :: a1) ● a2) = bind f (a :: a1) ● bind f a2
A, B: Type f: A -> list B a2: list A
bind f ([] ● a2) = bind f [] ● bind f a2
reflexivity.
A, B: Type f: A -> list B a: A a1, a2: list A IHa1: bind f (a1 ● a2) = bind f a1 ● bind f a2
bind f ((a :: a1) ● a2) = bind f (a :: a1) ● bind f a2
A, B: Type f: A -> list B a: A a1, a2: list A IHa1: bind f (a1 ● a2) = bind f a1 ● bind f a2
f a ● bind f (a1 ● a2) = (f a ● bind f a1) ● bind f a2
A, B: Type f: A -> list B a: A a1, a2: list A IHa1: bind f (a1 ● a2) = bind f a1 ● bind f a2
f a ● (bind f a1 ● bind f a2) =
(f a ● bind f a1) ● bind f a2
nowrewrite monoid_assoc.Qed.(** * Traversable Instance (Categorical) *)(**********************************************************************)From Tealeaves Require Import
Classes.Categorical.TraversableFunctor.#[global] InstanceDist_list: ApplicativeDist list :=
funGmapmltpurA =>
(fix dist (l: list (G A)) :=
match l with
| nil => pure nil
| cons x xs =>
pure (F := G) (@cons A) <⋆> x <⋆> (dist xs)
end).(** ** Rewriting Laws *)(**********************************************************************)Sectionlist_dist_rewrite.Context
`{Applicative G}.Variable (A: Type).
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type
dist list G [] = pure []
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type
dist list G [] = pure []
reflexivity.Qed.
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type
forall (x : G A) (xs : list (G A)),
dist list G (x :: xs) =
pure cons <⋆> x <⋆> dist list G xs
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type
forall (x : G A) (xs : list (G A)),
dist list G (x :: xs) =
pure cons <⋆> x <⋆> dist list G xs
reflexivity.Qed.
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type
forall (x : G A) (xs : list (G A)),
dist list G (x :: xs) = map cons x <⋆> dist list G xs
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type
forall (x : G A) (xs : list (G A)),
dist list G (x :: xs) = map cons x <⋆> dist list G xs
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type x: G A xs: list (G A)
dist list G (x :: xs) = map cons x <⋆> dist list G xs
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type x: G A xs: list (G A)
pure cons <⋆> x <⋆> dist list G xs =
map cons x <⋆> dist list G xs
nowrewrite map_to_ap.Qed.
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type a: G A
dist list G [a] = map ret a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type a: G A
dist list G [a] = map ret a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type a: G A
pure cons <⋆> a <⋆> pure [] = map ret a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type a: G A
pure cons <⋆> a <⋆> pure [] = pure ret <⋆> a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type a: G A
pure (evalAt []) <⋆> (pure cons <⋆> a) =
pure ret <⋆> a
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type a: G A
pure compose <⋆> pure (evalAt []) <⋆> pure cons <⋆> a =
pure ret <⋆> a
nowdo2rewrite ap2.Qed.
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type
foralll1l2 : list (G A),
dist list G (l1 ++ l2) =
pure (app (A:=A)) <⋆> dist list G l1 <⋆>
dist list G l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type
foralll1l2 : list (G A),
dist list G (l1 ++ l2) =
pure (app (A:=A)) <⋆> dist list G l1 <⋆>
dist list G l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type l1, l2: list (G A)
dist list G (l1 ++ l2) =
pure (app (A:=A)) <⋆> dist list G l1 <⋆>
dist list G l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type l2: list (G A)
dist list G ([] ++ l2) =
pure (app (A:=A)) <⋆> dist list G [] <⋆>
dist list G l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type a: G A l1, l2: list (G A) IHl1: dist list G (l1 ++ l2) =
pure (app (A:=A)) <⋆> dist list G l1 <⋆>
dist list G l2
dist list G ((a :: l1) ++ l2) =
pure (app (A:=A)) <⋆> dist list G (a :: l1) <⋆>
dist list G l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type l2: list (G A)
dist list G ([] ++ l2) =
pure (app (A:=A)) <⋆> dist list G [] <⋆>
dist list G l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type l2: list (G A)
dist list G l2 =
pure (app (A:=A)) <⋆> pure [] <⋆> dist list G l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type l2: list (G A)
dist list G l2 = pure (app []) <⋆> dist list G l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type l2: list (G A)
dist list G l2 = pure id <⋆> dist list G l2
nowrewrite ap1.
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type a: G A l1, l2: list (G A) IHl1: dist list G (l1 ++ l2) =
pure (app (A:=A)) <⋆> dist list G l1 <⋆>
dist list G l2
dist list G ((a :: l1) ++ l2) =
pure (app (A:=A)) <⋆> dist list G (a :: l1) <⋆>
dist list G l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type a: G A l1, l2: list (G A) IHl1: dist list G (l1 ++ l2) =
pure (app (A:=A)) <⋆> dist list G l1 <⋆>
dist list G l2
dist list G (a :: l1 ++ l2) =
pure (app (A:=A)) <⋆> dist list G (a :: l1) <⋆>
dist list G l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type a: G A l1, l2: list (G A) IHl1: dist list G (l1 ++ l2) =
pure (app (A:=A)) <⋆> dist list G l1 <⋆>
dist list G l2
map cons a <⋆> dist list G (l1 ++ l2) =
pure (app (A:=A)) <⋆> dist list G (a :: l1) <⋆>
dist list G l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type a: G A l1, l2: list (G A) IHl1: dist list G (l1 ++ l2) =
pure (app (A:=A)) <⋆> dist list G l1 <⋆>
dist list G l2
map cons a <⋆> dist list G (l1 ++ l2) =
pure (app (A:=A)) <⋆> (map cons a <⋆> dist list G l1) <⋆>
dist list G l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type a: G A l1, l2: list (G A)
map cons a <⋆>
(pure (app (A:=A)) <⋆> dist list G l1 <⋆>
dist list G l2) =
pure (app (A:=A)) <⋆> (map cons a <⋆> dist list G l1) <⋆>
dist list G l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type a: G A l1, l2: list (G A)
map cons a <⋆>
(map (app (A:=A)) (dist list G l1) <⋆> dist list G l2) =
pure (app (A:=A)) <⋆> (map cons a <⋆> dist list G l1) <⋆>
dist list G l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type a: G A l1, l2: list (G A)
map cons a <⋆>
(map (app (A:=A)) (dist list G l1) <⋆> dist list G l2) =
map (app (A:=A)) (map cons a <⋆> dist list G l1) <⋆>
dist list G l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type a: G A l1, l2: list (G A)
pure compose <⋆> map cons a <⋆>
map (app (A:=A)) (dist list G l1) <⋆> dist list G l2 =
map (app (A:=A)) (map cons a <⋆> dist list G l1) <⋆>
dist list G l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type a: G A l1, l2: list (G A)
map compose (map cons a) <⋆>
map (app (A:=A)) (dist list G l1) <⋆> dist list G l2 =
map (app (A:=A)) (map cons a <⋆> dist list G l1) <⋆>
dist list G l2
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type a: G A l1, l2: list (G A)
map compose (map cons a) <⋆>
map (app (A:=A)) (dist list G l1) =
map (app (A:=A)) (map cons a <⋆> dist list G l1)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type a: G A l1, l2: list (G A)
map (precompose (app (A:=A)))
(map compose (map cons a)) <⋆> dist list G l1 =
map (app (A:=A)) (map cons a <⋆> dist list G l1)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type a: G A l1, l2: list (G A)
map (precompose (app (A:=A)))
(map compose (map cons a)) <⋆> dist list G l1 =
map (compose (app (A:=A))) (map cons a) <⋆>
dist list G l1
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A: Type a: G A l1, l2: list (G A)
forall (G : Type -> Type) (Map_G : Map G)
(Pure_G : Pure G) (Mult_G : Mult G),
Applicative G ->
forall (AB : Type) (f : A -> B) (a : G A)
(l : list (G A)),
map G (map list f) (map G cons a <⋆> dist list G A l) =
map G (cons ○ f) a <⋆>
map G (map list f) (dist list G A l)
forall (G : Type -> Type) (Map_G : Map G)
(Pure_G : Pure G) (Mult_G : Mult G),
Applicative G ->
forall (AB : Type) (f : A -> B) (a : G A)
(l : list (G A)),
map G (map list f) (map G cons a <⋆> dist list G A l) =
map G (cons ○ f) a <⋆>
map G (map list f) (dist list G A l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A)
map G (map list f) (map G cons a <⋆> dist list G A l) =
map G (cons ○ f) a <⋆>
map G (map list f) (dist list G A l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A)
map G (compose (map list f)) (map G cons a) <⋆>
dist list G A l =
map G (cons ○ f) a <⋆>
map G (map list f) (dist list G A l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A)
map G (compose (map list f)) (map G cons a) <⋆>
dist list G A l =
map G (precompose (map list f)) (map G (cons ○ f) a) <⋆>
dist list G A l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A)
(map G (compose (map list f)) ∘ map G cons) a <⋆>
dist list G A l =
(map G (precompose (map list f)) ∘ map G (cons ○ f)) a <⋆>
dist list G A l
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A)
map G (compose (map list f) ∘ cons) a <⋆>
dist list G A l =
map G (precompose (map list f) ∘ (cons ○ f)) a <⋆>
dist list G A l
reflexivity.Qed.
forall (G : Type -> Type) (Map_G : Map G)
(Pure_G : Pure G) (Mult_G : Mult G),
Applicative G ->
forall (AB : Type) (f : A -> B) (a : G A)
(l : list (G A)),
map G (map list f)
(pure cons <⋆> a <⋆> dist list G A l) =
pure cons <⋆> map G f a <⋆>
map G (map list f) (dist list G A l)
forall (G : Type -> Type) (Map_G : Map G)
(Pure_G : Pure G) (Mult_G : Mult G),
Applicative G ->
forall (AB : Type) (f : A -> B) (a : G A)
(l : list (G A)),
map G (map list f)
(pure cons <⋆> a <⋆> dist list G A l) =
pure cons <⋆> map G f a <⋆>
map G (map list f) (dist list G A l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A)
map G (map list f)
(pure cons <⋆> a <⋆> dist list G A l) =
pure cons <⋆> map G f a <⋆>
map G (map list f) (dist list G A l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A)
map G (map list f) (map G cons a <⋆> dist list G A l) =
pure cons <⋆> map G f a <⋆>
map G (map list f) (dist list G A l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A)
map G (compose (map list f)) (map G cons a) <⋆>
dist list G A l =
pure cons <⋆> map G f a <⋆>
map G (map list f) (dist list G A l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A)
(map G (compose (map list f)) ∘ map G cons) a <⋆>
dist list G A l =
pure cons <⋆> map G f a <⋆>
map G (map list f) (dist list G A l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A)
map G (compose (map list f) ∘ cons) a <⋆>
dist list G A l =
pure cons <⋆> map G f a <⋆>
map G (map list f) (dist list G A l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A)
map G (compose (map list f) ∘ cons) a <⋆>
dist list G A l =
map G (cons ∘ f) a <⋆>
map G (map list f) (dist list G A l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A)
map G (fun '(f, a) => f a)
(map G (compose (map list f) ∘ cons) a
⊗ dist list G A l) =
map G (fun '(f, a) => f a)
(map G (cons ∘ f) a
⊗ map G (map list f) (dist list G A l))
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A)
map G (fun '(f, a) => f a)
(map G (compose (map list f) ∘ cons) a
⊗ dist list G A l) =
map G (fun '(f, a) => f a)
(map G (map_tensor (cons ∘ f) (map list f))
(a ⊗ dist list G A l))
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A)
map G
((fun '(f, a) => f a)
∘ map_fst (compose (map list f) ∘ cons))
(a ⊗ dist list G A l) =
map G (fun '(f, a) => f a)
(map G (map_tensor (cons ∘ f) (map list f))
(a ⊗ dist list G A l))
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A)
map G
((fun '(f, a) => f a)
∘ map_fst (compose (map list f) ∘ cons))
(a ⊗ dist list G A l) =
(map G (fun '(f, a) => f a)
∘ map G (map_tensor (cons ∘ f) (map list f)))
(a ⊗ dist list G A l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A)
map G
((fun '(f, a) => f a)
∘ map_fst (compose (map list f) ∘ cons))
(a ⊗ dist list G A l) =
map G
((fun '(f, a) => f a)
∘ map_tensor (cons ∘ f) (map list f))
(a ⊗ dist list G A l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A)
(fun '(f, a) => f a)
∘ map_fst (compose (map list f) ∘ cons) =
(fun '(f, a) => f a)
∘ map_tensor (cons ∘ f) (map list f)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A) a0: A l0: list A
((fun '(f, a) => f a)
∘ map_fst (compose (map list f) ∘ cons)) (a0, l0) =
((fun '(f, a) => f a)
∘ map_tensor (cons ∘ f) (map list f)) (a0, l0)
reflexivity.Qed.
forall (G : Type -> Type) (Map_G : Map G)
(Pure_G : Pure G) (Mult_G : Mult G),
Applicative G ->
forall (AB : Type) (f : A -> B),
map (G ∘ list) f ∘ dist list G A =
dist list G B ∘ map (list ∘ G) f
forall (G : Type -> Type) (Map_G : Map G)
(Pure_G : Pure G) (Mult_G : Mult G),
Applicative G ->
forall (AB : Type) (f : A -> B),
map (G ∘ list) f ∘ dist list G A =
dist list G B ∘ map (list ∘ G) f
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 ∘ list) f ∘ dist list G A =
dist list G B ∘ map (list ∘ G) f
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 (map list f) ∘ dist list G A =
dist list G B ∘ map list (map G f)
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 (map list f) ○ dist list G A =
dist list G B ○ map list (map G f)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B l: list (G A)
map G (map list f) (dist list G A l) =
dist list G B (map list (map G f) l)
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 (map list f) (dist list G A []) =
dist list G B (map list (map G f) [])
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A) IHl: map G (map list f) (dist list G A l) =
dist list G B (map list (map G f) l)
map G (map list f) (dist list G A (a :: l)) =
dist list G B (map list (map G f) (a :: l))
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 (map list f) (dist list G A []) =
dist list G B (map list (map G f) [])
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 (map list f) (pure []) = pure []
nowrewrite (app_pure_natural).
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A) IHl: map G (map list f) (dist list G A l) =
dist list G B (map list (map G f) l)
map G (map list f) (dist list G A (a :: l)) =
dist list G B (map list (map G f) (a :: l))
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A) IHl: map G (map list f) (dist list G A l) =
dist list G B (map list (map G f) l)
map G (map list f) (map G cons a <⋆> dist list G A l) =
dist list G B (map list (map G f) (a :: l))
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A) IHl: map G (map list f) (dist list G A l) =
dist list G B (map list (map G f) l)
map G (map list f) (map G cons a <⋆> dist list G A l) =
map G cons (map G f a) <⋆>
dist list G B (map list (map G f) l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A) IHl: map G (map list f) (dist list G A l) =
dist list G B (map list (map G f) l)
map G (map list f) (map G cons a <⋆> dist list G A l) =
map G cons (map G f a) <⋆>
map G (map list f) (dist list G A l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A) IHl: map G (map list f) (dist list G A l) =
dist list G B (map list (map G f) l)
map G (cons ○ f) a <⋆>
map G (map list f) (dist list G A l) =
map G cons (map G f a) <⋆>
map G (map list f) (dist list G A l)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G A, B: Type f: A -> B a: G A l: list (G A) IHl: map G (map list f) (dist list G A l) =
dist list G B (map list (map G f) l)
map G (cons ○ f) a <⋆>
map G (map list f) (dist list G A l) =
(map G cons ∘ map G f) a <⋆>
map G (map list f) (dist list G A l)
nowrewrite (fun_map_map).Qed.
forall (G : Type -> Type) (Map_G : Map G)
(Pure_G : Pure G) (Mult_G : Mult G),
Applicative G -> Natural (dist list G)
forall (G : Type -> Type) (Map_G : Map G)
(Pure_G : Pure G) (Mult_G : Mult G),
Applicative G -> Natural (dist list G)
G: Type -> Type Map_G: Map G Pure_G: Pure G Mult_G: Mult G H: Applicative G
forall (AB : Type) (f : A -> B),
map (G ○ list) f ∘ dist list G A =
dist list G B ∘ map (list ○ G) f
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 ○ list) f ∘ dist list G A =
dist list G B ∘ map (list ○ G) f
eapply (dist_natural_list f).Qed.
forall (G1G2 : Type -> Type) (H : Map G1)
(H0 : Mult G1) (H1 : Pure G1) (H2 : Map G2)
(H3 : Mult G2) (H4 : Pure G2)
(ϕ : forallA : Type, G1 A -> G2 A),
ApplicativeMorphism G1 G2 ϕ ->
forallA : Type,
dist list G2 A ∘ map list (ϕ A) =
ϕ (list A) ∘ dist list G1 A
forall (G1G2 : Type -> Type) (H : Map G1)
(H0 : Mult G1) (H1 : Pure G1) (H2 : Map G2)
(H3 : Mult G2) (H4 : Pure G2)
(ϕ : forallA : Type, G1 A -> G2 A),
ApplicativeMorphism G1 G2 ϕ ->
forallA : Type,
dist list G2 A ∘ map list (ϕ A) =
ϕ (list A) ∘ dist list G1 A
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A H5: ApplicativeMorphism G1 G2 ϕ A: Type
dist list G2 A ∘ map list (ϕ A) =
ϕ (list A) ∘ dist list G1 A
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A H5: ApplicativeMorphism G1 G2 ϕ A: Type l: list (G1 A)
(dist list G2 A ∘ map list (ϕ A)) l =
(ϕ (list A) ∘ dist list G1 A) l
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A H5: ApplicativeMorphism G1 G2 ϕ A: Type l: list (G1 A)
dist list G2 A (map list (ϕ A) l) =
ϕ (list A) (dist list G1 A l)
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A H5: ApplicativeMorphism G1 G2 ϕ A: Type
dist list G2 A (map list (ϕ A) []) =
ϕ (list A) (dist list G1 A [])
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A H5: ApplicativeMorphism G1 G2 ϕ A: Type a: G1 A l: list (G1 A) IHl: dist list G2 A (map list (ϕ A) l) = ϕ (list A) (dist list G1 A l)
dist list G2 A (map list (ϕ A) (a :: l)) =
ϕ (list A) (dist list G1 A (a :: l))
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A H5: ApplicativeMorphism G1 G2 ϕ A: Type
dist list G2 A (map list (ϕ A) []) =
ϕ (list A) (dist list G1 A [])
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A H5: ApplicativeMorphism G1 G2 ϕ A: Type
dist list G2 A [] = ϕ (list A) (dist list G1 A [])
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A H5: ApplicativeMorphism G1 G2 ϕ A: Type
pure [] = ϕ (list A) (dist list G1 A [])
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A H5: ApplicativeMorphism G1 G2 ϕ A: Type
pure [] = ϕ (list A) (pure [])
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A H5: ApplicativeMorphism G1 G2 ϕ A: Type
pure [] = pure []
reflexivity.
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A H5: ApplicativeMorphism G1 G2 ϕ A: Type a: G1 A l: list (G1 A) IHl: dist list G2 A (map list (ϕ A) l) = ϕ (list A) (dist list G1 A l)
dist list G2 A (map list (ϕ A) (a :: l)) =
ϕ (list A) (dist list G1 A (a :: l))
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A H5: ApplicativeMorphism G1 G2 ϕ A: Type a: G1 A l: list (G1 A) IHl: dist list G2 A (map list (ϕ A) l) = ϕ (list A) (dist list G1 A l) app1: Applicative G1 app2: Applicative G2
dist list G2 A (map list (ϕ A) (a :: l)) =
ϕ (list A) (dist list G1 A (a :: l))
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A H5: ApplicativeMorphism G1 G2 ϕ A: Type a: G1 A l: list (G1 A) IHl: dist list G2 A (map list (ϕ A) l) = ϕ (list A) (dist list G1 A l) app1: Applicative G1 app2: Applicative G2
dist list G2 A (ϕ A a :: map list (ϕ A) l) =
ϕ (list A) (dist list G1 A (a :: l))
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A H5: ApplicativeMorphism G1 G2 ϕ A: Type a: G1 A l: list (G1 A) IHl: dist list G2 A (map list (ϕ A) l) = ϕ (list A) (dist list G1 A l) app1: Applicative G1 app2: Applicative G2
map G2 cons (ϕ A a) <⋆>
dist list G2 A (map list (ϕ A) l) =
ϕ (list A) (dist list G1 A (a :: l))
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A H5: ApplicativeMorphism G1 G2 ϕ A: Type a: G1 A l: list (G1 A) IHl: dist list G2 A (map list (ϕ A) l) = ϕ (list A) (dist list G1 A l) app1: Applicative G1 app2: Applicative G2
map G2 cons (ϕ A a) <⋆>
dist list G2 A (map list (ϕ A) l) =
ϕ (list A) (map G1 cons a <⋆> dist list G1 A l)
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A H5: ApplicativeMorphism G1 G2 ϕ A: Type a: G1 A l: list (G1 A) IHl: dist list G2 A (map list (ϕ A) l) = ϕ (list A) (dist list G1 A l) app1: Applicative G1 app2: Applicative G2
map G2 cons (ϕ A a) <⋆> ϕ (list A) (dist list G1 A l) =
ϕ (list A) (map G1 cons a <⋆> dist list G1 A l)
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A H5: ApplicativeMorphism G1 G2 ϕ A: Type a: G1 A l: list (G1 A) IHl: dist list G2 A (map list (ϕ A) l) = ϕ (list A) (dist list G1 A l) app1: Applicative G1 app2: Applicative G2
map G2 cons (ϕ A a) <⋆> ϕ (list A) (dist list G1 A l) =
ϕ (list A -> list A) (map G1 cons a) <⋆>
ϕ (list A) (dist list G1 A l)
G1, G2: Type -> Type H: Map G1 H0: Mult G1 H1: Pure G1 H2: Map G2 H3: Mult G2 H4: Pure G2 ϕ: forallA : Type, G1 A -> G2 A H5: ApplicativeMorphism G1 G2 ϕ A: Type a: G1 A l: list (G1 A) IHl: dist list G2 A (map list (ϕ A) l) = ϕ (list A) (dist list G1 A l) app1: Applicative G1 app2: Applicative G2
map G2 cons (ϕ A a) <⋆> ϕ (list A) (dist list G1 A l) =
map G2 cons (ϕ A a) <⋆> ϕ (list A) (dist list G1 A l)
reflexivity.Qed.
forallA : Type,
dist list (funA0 : Type => A0) A = id
forallA : Type,
dist list (funA0 : Type => A0) A = id
A: Type
dist list (funA : Type => A) A = id
A: Type l: list A
dist list (funA : Type => A) A l = id l
A: Type
dist list (funA : Type => A) A [] = id []
A: Type a: A l: list A IHl: dist list (funA : Type => A) A l = id l
dist list (funA : Type => A) A (a :: l) = id (a :: l)
A: Type
dist list (funA : Type => A) A [] = id []
reflexivity.
A: Type a: A l: list A IHl: dist list (funA : Type => A) A l = id l
dist list (funA : Type => A) A (a :: l) = id (a :: l)
A: Type a: A l: list A IHl: dist list (funA : Type => A) A l = id l
pure cons a (dist list (funA : Type => A) A l) =
id (a :: l)
nowrewrite IHl.Qed.#[local] Set Keyed Unification.
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 ->
forallA : Type,
dist list (G1 ∘ G2) A =
map G1 (dist list G2 A) ∘ dist list G1 (G2 A)
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 ->
forallA : Type,
dist list (G1 ∘ G2) A =
map G1 (dist list G2 A) ∘ dist list G1 (G2 A)
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 list (G1 ∘ G2) A =
map G1 (dist list G2 A) ∘ dist list G1 (G2 A)
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 list (G1 ○ G2) A =
map G1 (dist list G2 A) ○ dist list G1 (G2 A)
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 l: list (G1 (G2 A))
dist list (G1 ○ G2) A l =
map G1 (dist list G2 A) (dist list G1 (G2 A) l)
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 list (G1 ○ G2) A [] =
map G1 (dist list G2 A) (dist list G1 (G2 A) [])
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 a: G1 (G2 A) l: list (G1 (G2 A)) IHl: dist list (G1 ○ G2) A l =
map G1 (dist list G2 A) (dist list G1 (G2 A) l)
dist list (G1 ○ G2) A (a :: l) =
map G1 (dist list G2 A) (dist list G1 (G2 A) (a :: l))
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 list (G1 ○ G2) A [] =
map G1 (dist list G2 A) (dist list G1 (G2 A) [])
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
pure [] = map G1 (dist list G2 A) (pure [])
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
pure (pure []) = map G1 (dist list G2 A) (pure [])
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
pure (pure []) = pure (dist list G2 A) <⋆> pure []
nowrewrite ap2.
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 a: G1 (G2 A) l: list (G1 (G2 A)) IHl: dist list (G1 ○ G2) A l =
map G1 (dist list G2 A) (dist list G1 (G2 A) l)
dist list (G1 ○ G2) A (a :: l) =
map G1 (dist list G2 A) (dist list G1 (G2 A) (a :: l))
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 a: G1 (G2 A) l: list (G1 (G2 A)) IHl: dist list (G1 ○ G2) A l =
map G1 (dist list G2 A) (dist list G1 (G2 A) l)
map (G1 ○ G2) cons a <⋆> dist list (G1 ○ G2) A l =
map G1 (dist list G2 A) (dist list G1 (G2 A) (a :: l))
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 a: G1 (G2 A) l: list (G1 (G2 A)) IHl: dist list (G1 ○ G2) A l =
map G1 (dist list G2 A) (dist list G1 (G2 A) l)
map (G1 ○ G2) cons a <⋆> dist list (G1 ○ G2) A l =
map G1 (dist list G2 A)
(map G1 cons a <⋆> dist list G1 (G2 A) l)
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 a: G1 (G2 A) l: list (G1 (G2 A))
map (G1 ○ G2) cons a <⋆>
map G1 (dist list G2 A) (dist list G1 (G2 A) l) =
map G1 (dist list G2 A)
(map G1 cons a <⋆> dist list G1 (G2 A) l)
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 a: G1 (G2 A) l: list (G1 (G2 A))
map G1 (map G2 cons) a <⋆>
map G1 (dist list G2 A) (dist list G1 (G2 A) l) =
map G1 (dist list G2 A)
(map G1 cons a <⋆> dist list G1 (G2 A) l)
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 a: G1 (G2 A) l: list (G1 (G2 A))
map G1 (ap G2) (map G1 (map G2 cons) a) <⋆>
map G1 (dist list G2 A) (dist list G1 (G2 A) l) =
map G1 (dist list G2 A)
(map G1 cons a <⋆> dist list G1 (G2 A) l)
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 a: G1 (G2 A) l: list (G1 (G2 A))
(map G1 (ap G2) ∘ map G1 (map G2 cons)) a <⋆>
map G1 (dist list G2 A) (dist list G1 (G2 A) l) =
map G1 (dist list G2 A)
(map G1 cons a <⋆> dist list G1 (G2 A) l)
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 a: G1 (G2 A) l: list (G1 (G2 A))
map G1 (ap G2 ∘ map G2 cons) a <⋆>
map G1 (dist list G2 A) (dist list G1 (G2 A) l) =
map G1 (dist list G2 A)
(map G1 cons a <⋆> dist list G1 (G2 A) l)
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 a: G1 (G2 A) l: list (G1 (G2 A))
map G1 (fun '(f, a) => f a)
(map G1 (ap G2 ∘ map G2 cons) a
⊗ map G1 (dist list G2 A) (dist list G1 (G2 A) l)) =
map G1 (dist list G2 A)
(map G1 cons a <⋆> dist list G1 (G2 A) l)
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 a: G1 (G2 A) l: list (G1 (G2 A))
map G1 (fun '(f, a) => f a)
(map G1
(map_tensor (ap G2 ∘ map G2 cons)
(dist list G2 A)) (a ⊗ dist list G1 (G2 A) l)) =
map G1 (dist list G2 A)
(map G1 cons a <⋆> dist list G1 (G2 A) l)
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 a: G1 (G2 A) l: list (G1 (G2 A))
map G1 (fun '(f, a) => f a)
(map G1
(map_tensor (ap G2 ∘ map G2 cons)
(dist list G2 A)) (a ⊗ dist list G1 (G2 A) l)) =
map G1 (dist list G2 A)
(map G1 (fun '(f, a) => f a)
(map G1 cons a ⊗ dist list G1 (G2 A) l))
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 a: G1 (G2 A) l: list (G1 (G2 A))
map G1 (fun '(f, a) => f a)
(map G1
(map_tensor (ap G2 ∘ map G2 cons)
(dist list G2 A)) (a ⊗ dist list G1 (G2 A) l)) =
map G1 (dist list G2 A)
(map G1 ((fun '(f, a) => f a) ∘ map_fst cons)
(a ⊗ dist list G1 (G2 A) l))
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 a: G1 (G2 A) l: list (G1 (G2 A))
map G1 (fun '(f, a) => f a)
(map G1
(map_tensor (ap G2 ∘ map G2 cons)
(dist list G2 A)) (a ⊗ dist list G1 (G2 A) l)) =
map G1 (dist list G2 A)
(map G1 ((fun '(f, a) => f a) ∘ map_fst cons)
(a ⊗ dist list G1 (G2 A) l))
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 a: G1 (G2 A) l: list (G1 (G2 A))
(map G1 (fun '(f, a) => f a)
∘ map G1
(map_tensor (ap G2 ∘ map G2 cons)
(dist list G2 A))) (a ⊗ dist list G1 (G2 A) l) =
(map G1 (dist list G2 A)
∘ map G1 ((fun '(f, a) => f a) ∘ map_fst cons))
(a ⊗ dist list G1 (G2 A) l)
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 a: G1 (G2 A) l: list (G1 (G2 A))
map G1
((fun '(f, a) => f a)
∘ map_tensor (ap G2 ∘ map G2 cons) (dist list G2 A))
(a ⊗ dist list G1 (G2 A) l) =
(map G1 (dist list G2 A)
∘ map G1 ((fun '(f, a) => f a) ∘ map_fst cons))
(a ⊗ dist list G1 (G2 A) l)
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 a: G1 (G2 A) l: list (G1 (G2 A))
map G1
((fun '(f, a) => f a)
∘ map_tensor (ap G2 ∘ map G2 cons) (dist list G2 A))
(a ⊗ dist list G1 (G2 A) l) =
map G1
(dist list G2 A
∘ ((fun '(f, a) => f a) ∘ map_fst cons))
(a ⊗ dist list G1 (G2 A) l)
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 a: G1 (G2 A) l: list (G1 (G2 A))
(fun '(f, a) => f a)
∘ map_tensor (ap G2 ∘ map G2 cons) (dist list G2 A) =
dist list G2 A ∘ ((fun '(f, a) => f a) ∘ map_fst cons)
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 a: G1 (G2 A) l: list (G1 (G2 A)) g: G2 A l0: list (G2 A)
((fun '(f, a) => f a)
∘ map_tensor (ap G2 ∘ map G2 cons) (dist list G2 A))
(g, l0) =
(dist list G2 A
∘ ((fun '(f, a) => f a) ∘ map_fst cons)) (g, l0)
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 a: G1 (G2 A) l: list (G1 (G2 A)) g: G2 A l0: list (G2 A)
(ap G2 ∘ map G2 cons) g (dist list G2 A l0) =
pure cons <⋆> g <⋆> dist list G2 A (id l0)
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 a: G1 (G2 A) l: list (G1 (G2 A)) g: G2 A l0: list (G2 A)
map G2 cons g <⋆> dist list G2 A l0 =
pure cons <⋆> g <⋆> dist list G2 A (id l0)
nowrewrite map_to_ap.Qed.#[local] Unset Keyed Unification.Enddist_list_properties.(** ** Typeclass Instance *)(**********************************************************************)#[export] InstanceTraversable_Categorical_list: Categorical.TraversableFunctor.TraversableFunctor list :=
{| dist_natural := @dist_natural_list_;
dist_morph := @dist_morph_list;
dist_unit := @dist_unit_list;
dist_linear := @dist_linear_list;
|}.(** * Folding over lists *)(**********************************************************************)Fixpointcrush_list
`{op: Monoid_op M}
`{unit: Monoid_unit M} (l: list M): M :=
match l with
| nil => Ƶ
| cons x l' => x ● crush_list l'
end.(** ** Rewriting Laws for [crush_list] *)(**********************************************************************)Sectioncrush_list_rewriting_lemmas.Context
`{Monoid M}.
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
crush_list [] = Ƶ
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
crush_list [] = Ƶ
reflexivity.Qed.
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
forall (m : M) (l : list M),
crush_list (m :: l) = m ● crush_list l
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
forall (m : M) (l : list M),
crush_list (m :: l) = m ● crush_list l
reflexivity.Qed.
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
forallm : M, crush_list [m] = m
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
forallm : M, crush_list [m] = m
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M m: M
crush_list [m] = m
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M m: M
m ● Ƶ = m
now simpl_monoid.Qed.
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
foralll1l2 : list M,
crush_list (l1 ++ l2) = crush_list l1 ● crush_list l2
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
foralll1l2 : list M,
crush_list (l1 ++ l2) = crush_list l1 ● crush_list l2
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M l1, l2: list M
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M a: M l1, l2: list M IHl: crush_list (l1 ++ l2) =
crush_list l1 ● crush_list l2
a ● crush_list (l1 ++ l2) =
(a ● crush_list l1) ● crush_list l2
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M a: M l1, l2: list M IHl: crush_list (l1 ++ l2) =
crush_list l1 ● crush_list l2
a ● (crush_list l1 ● crush_list l2) =
(a ● crush_list l1) ● crush_list l2
now simpl_monoid.Qed.Endcrush_list_rewriting_lemmas.(** ** <<crush_list>> is a Monoid Morphism *)(** <<crush_list: list M -> M>> is homomorphism of monoids. *)(**********************************************************************)#[export] InstanceMonmor_crush_list (M: Type) `{Monoid M}:
Monoid_Morphism (list M) M crush_list :=
{| monmor_unit := crush_list_nil;
monmor_op := crush_list_app;
|}.(** ** Miscellaneous properties *)(**********************************************************************)(** *** <<crush_list>> commutes with monoid homomorphisms *)
nowrewrite (monmor_op (ϕ := ϕ)), IHl.Qed.(** *** <<crush_list>> for the list monoid is <<join>> *)
forallA : Type, crush_list = join
forallA : Type, crush_list = join
A: Type
crush_list = join
A: Type l: list (list A)
crush_list l = join l
A: Type
crush_list [] = join []
A: Type a: list A l: list (list A) IHl: crush_list l = join l
crush_list (a :: l) = join (a :: l)
A: Type
crush_list [] = join []
reflexivity.
A: Type a: list A l: list (list A) IHl: crush_list l = join l
crush_list (a :: l) = join (a :: l)
A: Type a: list A l: list (list A) IHl: crush_list l = join l
a ● crush_list l = a ++ join l
nowrewrite IHl.Qed.(** ** The <<mapReduce_list>> Operation *)(**********************************************************************)DefinitionmapReduce_list {M: Type} `{op: Monoid_op M}
`{unit: Monoid_unit M} {A: Type} (f: A -> M):
list A -> M := crush_list ∘ map f.(** ** <<mapReduce_list>> is a Monoid Homomorphism *)(**********************************************************************)(** <<mapReduce_list>> is a monoid homomorphism *)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A: Type f: A -> M
Monoid_Morphism (list A) M (mapReduce_list f)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A: Type f: A -> M
Monoid_Morphism (list A) M (mapReduce_list f)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A: Type f: A -> M
Monoid_Morphism (list A) M (crush_list ∘ map f)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A: Type f: A -> M
Monoid (list A)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A: Type f: A -> M
Monoid M
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A: Type f: A -> M
Monoid_Morphism (list A) (list M) (map f)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A: Type f: A -> M
Monoid_Morphism (list M) M crush_list
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A: Type f: A -> M
Monoid (list A)
typeclasses eauto.
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A: Type f: A -> M
Monoid M
typeclasses eauto.
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A: Type f: A -> M
Monoid_Morphism (list A) (list M) (map f)
typeclasses eauto.
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M A: Type f: A -> M
Monoid_Morphism (list M) M crush_list
typeclasses eauto.Qed.(** ** <<mapReduce_list>> Commutes with Monoid Homomorphism *)(**********************************************************************)
reflexivity.Qed.(** ** Rewriting Laws for <<mapReduce_list>> *)(**********************************************************************)SectionmapReduce_list_rw.Context
{AM: Type}
`{Monoid M}
(f: A -> M).
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M
mapReduce_list f [] = Ƶ
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M
mapReduce_list f [] = Ƶ
reflexivity.Qed.
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M
forall (x : A) (xs : list A),
mapReduce_list f (x :: xs) = f x ● mapReduce_list f xs
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M
forall (x : A) (xs : list A),
mapReduce_list f (x :: xs) = f x ● mapReduce_list f xs
reflexivity.Qed.
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M a: A
mapReduce_list f [a] = f a
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M a: A
mapReduce_list f [a] = f a
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M a: A
op (f a) unit0 = f a
apply monoid_id_r.Qed.
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M
mapReduce_list f ∘ ret = f
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M
mapReduce_list f ∘ ret = f
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M a: A
f a ● Ƶ = f a
apply monoid_id_r.Qed.
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M
foralll1l2 : list A,
mapReduce_list f (l1 ++ l2) =
mapReduce_list f l1 ● mapReduce_list f l2
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M
foralll1l2 : list A,
mapReduce_list f (l1 ++ l2) =
mapReduce_list f l1 ● mapReduce_list f l2
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M l1, l2: list A
mapReduce_list f (l1 ++ l2) =
mapReduce_list f l1 ● mapReduce_list f l2
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M l1, l2: list A
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M l1, l2: list A
crush_list (map f (l1 ++ l2)) =
crush_list (map f l1) ● crush_list (map f l2)
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M l1, l2: list A
crush_list (map f l1 ++ map f l2) =
crush_list (map f l1) ● crush_list (map f l2)
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M l1, l2: list A
crush_list (map f l1) ● crush_list (map f l2) =
crush_list (map f l1) ● crush_list (map f l2)
reflexivity.Qed.EndmapReduce_list_rw.#[export] Hint Rewrite @mapReduce_list_nil @mapReduce_list_cons
@mapReduce_list_one @mapReduce_list_app: tea_list.
forallA : Type, mapReduce_list ret = id
forallA : Type, mapReduce_list ret = id
A: Type
mapReduce_list ret = id
A: Type l: list A
mapReduce_list ret l = id l
A: Type
Ƶ = id []
A: Type x: A rest: list A IHrest: mapReduce_list ret rest = id rest
ret x ● mapReduce_list ret rest = id (x :: rest)
A: Type x: A rest: list A IHrest: mapReduce_list ret rest = id rest
ret x ● mapReduce_list ret rest = id (x :: rest)
nowrewrite IHrest.Qed.(** ** Monoids form list (monad-)algebras *)(** In fact, list algebras are precisely monoids. *)(**********************************************************************)Sectionfoldable_list.Context
`{Monoid M}.
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
forallx : M, crush_list (ret x : list M) = x
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
forallx : M, crush_list (ret x : list M) = x
apply monoid_id_r.Qed.
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
foralll : list (list M),
crush_list (join l) = crush_list (map crush_list l)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
foralll : list (list M),
crush_list (join l) = crush_list (map crush_list l)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M l: list (list M)
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M l: list (list M)
(crush_list ∘ crush_list) l =
crush_list (map crush_list l)
nowrewrite (crush_list_mon_hom crush_list).Qed.
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
foralll : list M,
crush_list (map (fun_ : M => Ƶ) l) = Ƶ
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
foralll : list M,
crush_list (map (fun_ : M => Ƶ) l) = Ƶ
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M l: list M
crush_list (map (fun_ : M => Ƶ) l) = Ƶ
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
crush_list (map (fun_ : M => Ƶ) []) = Ƶ
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M a: M l: list M IHl: crush_list (map (fun_ : M => Ƶ) l) = Ƶ
crush_list (map (fun_ : M => Ƶ) (a :: l)) = Ƶ
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M
crush_list (map (fun_ : M => Ƶ) []) = Ƶ
reflexivity.
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M a: M l: list M IHl: crush_list (map (fun_ : M => Ƶ) l) = Ƶ
crush_list (map (fun_ : M => Ƶ) (a :: l)) = Ƶ
M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M a: M l: list M IHl: crush_list (map (fun_ : M => Ƶ) l) = Ƶ
Ƶ ● crush_list (map (fun_ : M => Ƶ) l) = Ƶ
now simpl_monoid.Qed.Endfoldable_list.(** * Container Instance *)(**********************************************************************)#[export] InstanceToSubset_list: ToSubset list :=
fun (A: Type) (l: list A) => (funa: A => @List.In A a l).(** ** Rewriting Laws for <<tosubset>> *)(**********************************************************************)
forallA : Type, tosubset [] = ∅
forallA : Type, tosubset [] = ∅
A: Type
tosubset [] = ∅
A: Type a: A
tosubset [] a = ∅ a
reflexivity.Qed.
forall (A : Type) (a : A), tosubset [a] = {{a}}
forall (A : Type) (a : A), tosubset [a] = {{a}}
A: Type a: A
tosubset [a] = {{a}}
solve_basic_subset.Qed.
forall (A : Type) (a : A), tosubset (ret a) = {{a}}
forall (A : Type) (a : A), tosubset (ret a) = {{a}}
A: Type a: A
tosubset (ret a) = {{a}}
solve_basic_subset.Qed.
forall (A : Type) (a : A) (l : list A),
tosubset (a :: l) = {{a}} ∪ tosubset l
forall (A : Type) (a : A) (l : list A),
tosubset (a :: l) = {{a}} ∪ tosubset l
A: Type a: A l: list A
tosubset (a :: l) = {{a}} ∪ tosubset l
A: Type a: A l: list A a': A
tosubset (a :: l) a' = ({{a}} ∪ tosubset l) a'
reflexivity.Qed.
forall (A : Type) (l1l2 : list A),
tosubset (l1 ++ l2) = tosubset l1 ∪ tosubset l2
forall (A : Type) (l1l2 : list A),
tosubset (l1 ++ l2) = tosubset l1 ∪ tosubset l2
A: Type l1, l2: list A
tosubset (l1 ++ l2) = tosubset l1 ∪ tosubset l2
A: Type l2: list A
tosubset ([] ++ l2) = tosubset [] ∪ tosubset l2
A: Type a: A l1, l2: list A IHl1: tosubset (l1 ++ l2) = tosubset l1 ∪ tosubset l2
forall (a : A) (xsys : list A),
a ∈ (xs ++ ys) <-> a ∈ xs \/ a ∈ ys
A: Type
forall (a : A) (xsys : list A),
a ∈ (xs ++ ys) <-> a ∈ xs \/ a ∈ ys
A: Type a: A xs, ys: list A
a ∈ (xs ++ ys) <-> a ∈ xs \/ a ∈ ys
A: Type a: A xs, ys: list A
tosubset (xs ++ ys) a <->
tosubset xs a \/ tosubset ys a
A: Type a: A xs, ys: list A
tosubset xs a \/ tosubset ys a <->
tosubset xs a \/ tosubset ys a
easy.Qed.(* TODO: element_of_list_nil is sometimes applied at weird times, e.g.: Hint Rewrite @element_of_list_nil: tea_test. Goal (@monoid_unit Prop Monoid_unit_false). autorewrite with tea_test. Abort. I'm not sure what is causing this behavior *)#[export] Hint Rewrite(* @element_of_list_nil *)
@element_of_list_cons @element_of_list_one
@element_of_list_ret @element_of_list_app: tea_list.(** ** <<x ∈>> is a Monoid Homomorphism *)(**********************************************************************)
A: Type a: A
Monoid_Morphism (list A) Prop (element_of a)
A: Type a: A
Monoid_Morphism (list A) Prop (element_of a)
A: Type a: A
Monoid_Morphism (list A) Prop (evalAt a ∘ tosubset)
forall (AB : Type) (fg : A -> B) (l : list A),
(foralla : A, a ∈ l -> f a = g a) <->
map f l = map g l
forall (AB : Type) (fg : A -> B) (l : list A),
(foralla : A, a ∈ l -> f a = g a) <->
map f l = map g l
A, B: Type f, g: A -> B l: list A
(foralla : A, a ∈ l -> f a = g a) <->
map f l = map g l
A, B: Type f, g: A -> B
(foralla : A, a ∈ [] -> f a = g a) <->
map f [] = map g []
A, B: Type f, g: A -> B a: A l: list A IHl: (foralla : A, a ∈ l -> f a = g a) <-> map f l = map g l
(foralla0 : A, a0 ∈ (a :: l) -> f a0 = g a0) <->
map f (a :: l) = map g (a :: l)
A, B: Type f, g: A -> B
(foralla : A, a ∈ [] -> f a = g a) <->
map f [] = map g []
A, B: Type f, g: A -> B
(foralla : A, a ∈ [] -> f a = g a) <-> [] = []
A, B: Type f, g: A -> B
(foralla : A, False -> f a = g a) <-> [] = []
tauto.
A, B: Type f, g: A -> B a: A l: list A IHl: (foralla : A, a ∈ l -> f a = g a) <-> map f l = map g l
(foralla0 : A, a0 ∈ (a :: l) -> f a0 = g a0) <->
map f (a :: l) = map g (a :: l)
A, B: Type f, g: A -> B a: A l: list A IHl: (foralla : A, a ∈ l -> f a = g a) <-> map f l = map g l
(foralla0 : A, a0 ∈ (a :: l) -> f a0 = g a0) <->
f a :: map f l = g a :: map g l
A, B: Type f, g: A -> B a: A l: list A IHl: (foralla : A, a ∈ l -> f a = g a) <-> map f l = map g l
(foralla0 : A, a0 = a \/ a0 ∈ l -> f a0 = g a0) <->
f a :: map f l = g a :: map g l
A, B: Type f, g: A -> B a: A l: list A H: (foralla : A, a ∈ l -> f a = g a) ->
map f l = map g l H0: map f l = map g l ->
foralla : A, a ∈ l -> f a = g a
(foralla0 : A, a0 = a \/ a0 ∈ l -> f a0 = g a0) <->
f a :: map f l = g a :: map g l
A, B: Type f, g: A -> B a: A l: list A H: (foralla : A, a ∈ l -> f a = g a) ->
map f l = map g l H0: map f l = map g l ->
foralla : A, a ∈ l -> f a = g a
(foralla0 : A, a0 = a \/ a0 ∈ l -> f a0 = g a0) ->
f a :: map f l = g a :: map g l
A, B: Type f, g: A -> B a: A l: list A H: (foralla : A, a ∈ l -> f a = g a) ->
map f l = map g l H0: map f l = map g l ->
foralla : A, a ∈ l -> f a = g a
f a :: map f l = g a :: map g l ->
foralla0 : A, a0 = a \/ a0 ∈ l -> f a0 = g a0
A, B: Type f, g: A -> B a: A l: list A H: (foralla : A, a ∈ l -> f a = g a) ->
map f l = map g l H0: map f l = map g l ->
foralla : A, a ∈ l -> f a = g a
(foralla0 : A, a0 = a \/ a0 ∈ l -> f a0 = g a0) ->
f a :: map f l = g a :: map g l
intro; fequal; auto.
A, B: Type f, g: A -> B a: A l: list A H: (foralla : A, a ∈ l -> f a = g a) ->
map f l = map g l H0: map f l = map g l ->
foralla : A, a ∈ l -> f a = g a
f a :: map f l = g a :: map g l ->
foralla0 : A, a0 = a \/ a0 ∈ l -> f a0 = g a0
injection1; intuition (subst; auto).Qed.
forall (AB : Type) (l : list A) (fg : A -> B),
(foralla : A, a ∈ l -> f a = g a) ->
map f l = map g l
forall (AB : Type) (l : list A) (fg : A -> B),
(foralla : A, a ∈ l -> f a = g a) ->
map f l = map g l
A, B: Type l: list A f, g: A -> B H: foralla : A, a ∈ l -> f a = g a
map f l = map g l
nowrewrite <- map_rigidly_respectful_list.Qed.#[export] InstanceContainerFunctor_list: ContainerFunctor list :=
{| cont_pointwise := map_respectful_list;
|}.(** ** <<tosubset>> as a Monad Homomorphism *)(**********************************************************************)
forallA : Type, tosubset ∘ ret = ret
forallA : Type, tosubset ∘ ret = ret
A: Type
tosubset ∘ ret = ret
A: Type a, b: A
(tosubset ∘ ret) a b = ret a b
propext;
cbv; intuition.Qed.
forall (AB : Type) (f : A -> list B),
tosubset ∘ bind f = bind (tosubset ∘ f) ∘ tosubset
forall (AB : Type) (f : A -> list B),
tosubset ∘ bind f = bind (tosubset ∘ f) ∘ tosubset
tosubset (bind f l) b =
bind (tosubset ○ f) (tosubset l) b
A, B: Type f: A -> list B b: B
tosubset (bind f []) b =
bind (tosubset ○ f) (tosubset []) b
A, B: Type f: A -> list B a: A l: list A b: B IHl: tosubset (bind f l) b = bind (tosubset ○ f) (tosubset l) b
tosubset (bind f (a :: l)) b =
bind (tosubset ○ f) (tosubset (a :: l)) b
A, B: Type f: A -> list B b: B
tosubset (bind f []) b =
bind (tosubset ○ f) (tosubset []) b
A, B: Type f: A -> list B b: B
False ->
existsa : A,
False /\
(fix In (a0 : B) (l : list B) {struct l} : Prop :=
match l with
| [] => False
| b :: m => b = a0 \/ In a0 m
end) b (f a)
A, B: Type f: A -> list B b: B
(existsa : A,
False /\
(fix In (a0 : B) (l : list B) {struct l} : Prop :=
match l with
| [] => False
| b :: m => b = a0 \/ In a0 m
end) b (f a)) -> False
A, B: Type f: A -> list B b: B
False ->
existsa : A,
False /\
(fix In (a0 : B) (l : list B) {struct l} : Prop :=
match l with
| [] => False
| b :: m => b = a0 \/ In a0 m
end) b (f a)
intuition.
A, B: Type f: A -> list B b: B
(existsa : A,
False /\
(fix In (a0 : B) (l : list B) {struct l} : Prop :=
match l with
| [] => False
| b :: m => b = a0 \/ In a0 m
end) b (f a)) -> False
intros [a [absurd]]; contradiction.
A, B: Type f: A -> list B a: A l: list A b: B IHl: tosubset (bind f l) b = bind (tosubset ○ f) (tosubset l) b
tosubset (bind f (a :: l)) b =
bind (tosubset ○ f) (tosubset (a :: l)) b
A, B: Type f: A -> list B a: A l: list A b: B IHl: tosubset (bind f l) b = bind (tosubset ○ f) (tosubset l) b
(tosubset (f a) b \/ tosubset (bind f l) b) =
(tosubset (f a) b \/
bind (tosubset ○ f) (tosubset l) b)
A, B: Type f: A -> list B a: A l: list A b: B IHl: tosubset (bind f l) b = bind (tosubset ○ f) (tosubset l) b
(tosubset (f a) b \/
bind (tosubset ○ f) (tosubset l) b) =
(tosubset (f a) b \/
bind (tosubset ○ f) (tosubset l) b)
reflexivity.Qed.
forall (AB : Type) (f : A -> B),
tosubset ∘ map f = map f ∘ tosubset
forall (AB : Type) (f : A -> B),
tosubset ∘ map f = map f ∘ tosubset
A, B: Type f: A -> B
tosubset ∘ map f = map f ∘ tosubset
nowrewrite <- (natural (ϕ := @tosubset list _)).Qed.#[export] InstanceMonad_Hom_list_tosubset:
MonadHom list subset (@tosubset list _) :=
{| kmon_hom_ret := tosubset_list_hom1;
kmon_hom_bind := tosubset_list_hom2;
|}.