@@ -86,28 +86,30 @@ We can use traverse and const to construct this composition:
86
86
And this is how `const` turns a monoid into an applicative functor and
87
87
how the monoid of endofunctions define `foldl`.
88
88
-/
89
- @[reducible] def foldl (α : Type u) : Type u := End α
90
- def foldl.mk (f : α → α) : foldl α := f
89
+ @[reducible] def foldl (α : Type u) : Type u := (End α)ᵒᵖ
90
+ def foldl.mk (f : α → α) : foldl α := op f
91
+ def foldl.get (x : foldl α) : α → α := unop x
91
92
def foldl.of_free_monoid (f : β → α → β) (xs : free_monoid α) : monoid.foldl β :=
92
- flip (list.foldl f) xs
93
+ op $ flip (list.foldl f) xs
93
94
94
- @[reducible] def foldr (α : Type u) : Type u := opposite ( End α)
95
- def foldr.mk (f : α → α) : foldr α := op f
96
- def foldr.get (x : foldr α) : α → α := unop x
95
+ @[reducible] def foldr (α : Type u) : Type u := End α
96
+ def foldr.mk (f : α → α) : foldr α := f
97
+ def foldr.get (x : foldr α) : α → α := x
97
98
def foldr.of_free_monoid (f : α → β → β) (xs : free_monoid α) : monoid.foldr β :=
98
- op $ flip (list.foldr f) xs
99
+ flip (list.foldr f) xs
99
100
100
- @[reducible] def mfoldl (m : Type u → Type u) [monad m] (α : Type u) : Type u := End $ Kleisli.mk m α
101
- def mfoldl.mk (f : α → m α) : mfoldl m α := f
101
+ @[reducible] def mfoldl (m : Type u → Type u) [monad m] (α : Type u) : Type u := opposite $ End $ Kleisli.mk m α
102
+ def mfoldl.mk (f : α → m α) : mfoldl m α := op f
103
+ def mfoldl.get (x : mfoldl m α) : α → m α := unop x
102
104
def mfoldl.of_free_monoid (f : β → α → m β) (xs : free_monoid α) : monoid.mfoldl m β :=
103
- flip (list.mfoldl f) xs
105
+ op $ flip (list.mfoldl f) xs
104
106
105
107
@[reducible] def mfoldr (m : Type u → Type u) [monad m] (α : Type u) : Type u :=
106
- opposite ( End $ Kleisli.mk m α)
107
- def mfoldr.mk (f : α → m α) : mfoldr m α := op f
108
- def mfoldr.get (x : mfoldr m α) : α → m α := unop x
108
+ End $ Kleisli.mk m α
109
+ def mfoldr.mk (f : α → m α) : mfoldr m α := f
110
+ def mfoldr.get (x : mfoldr m α) : α → m α := x
109
111
def mfoldr.of_free_monoid (f : α → β → m β) (xs : free_monoid α) : monoid.mfoldr m β :=
110
- op $ flip (list.mfoldr f) xs
112
+ flip (list.mfoldr f) xs
111
113
112
114
end monoid
113
115
@@ -121,10 +123,10 @@ def fold_map {α ω} [has_one ω] [has_mul ω] (f : α → ω) : t α → ω :=
121
123
traverse (const.mk' ∘ f)
122
124
123
125
def foldl (f : α → β → α) (x : α) (xs : t β) : α :=
124
- fold_map (foldl.mk ∘ flip f) xs x
126
+ ( fold_map (foldl.mk ∘ flip f) xs).get x
125
127
126
128
def foldr (f : α → β → β) (x : β) (xs : t α) : β :=
127
- unop (fold_map (foldr.mk ∘ f) xs) x
129
+ (fold_map (foldr.mk ∘ f) xs).get x
128
130
129
131
/--
130
132
Conceptually, `to_list` collects all the elements of a collection
@@ -152,10 +154,10 @@ down $ foldl (λ l _, up $ l.down + 1) (up 0) xs
152
154
variables {m : Type u → Type u} [monad m]
153
155
154
156
def mfoldl (f : α → β → m α) (x : α) (xs : t β) : m α :=
155
- fold_map (mfoldl.mk ∘ flip f) xs x
157
+ ( fold_map (mfoldl.mk ∘ flip f) xs).get x
156
158
157
159
def mfoldr (f : α → β → m β) (x : β) (xs : t α) : m β :=
158
- unop (fold_map (mfoldr.mk ∘ f) xs) x
160
+ (fold_map (mfoldr.mk ∘ f) xs).get x
159
161
160
162
end defs
161
163
@@ -184,32 +186,31 @@ instance (f : α → β) : is_monoid_hom (free.map f) :=
184
186
instance fold_foldl (f : β → α → β) :
185
187
is_monoid_hom (foldl.of_free_monoid f) :=
186
188
{ map_one := rfl,
187
- map_mul := by { intros, unfold_projs, simp only [foldl.of_free_monoid, flip, list.foldl_append], } }
189
+ map_mul := by intros; simp only [free_monoid.mul_def, foldl.of_free_monoid, flip, unop_op, list.foldl_append, op_inj_iff]; refl }
188
190
189
- lemma foldr .unop_of_free_monoid (f : α → β → β) (xs : free_monoid α) (a : β) :
190
- unop (foldr .of_free_monoid f xs) a = list.foldr f a xs := rfl
191
+ lemma foldl .unop_of_free_monoid (f : β → α → β) (xs : free_monoid α) (a : β) :
192
+ unop (foldl .of_free_monoid f xs) a = list.foldl f a xs := rfl
191
193
192
194
instance fold_foldr (f : α → β → β) :
193
195
is_monoid_hom (foldr.of_free_monoid f) :=
194
196
{ map_one := rfl,
195
- map_mul := by { intros, apply unop_inj, ext, simp only [foldr.of_free_monoid,flip,free_add_monoid.add_def, list.foldr_append], refl } }
197
+ map_mul := by intros; simp only [free_monoid.mul_def, foldr.of_free_monoid, list.foldr_append, flip]; refl }
196
198
197
199
variables (m : Type u → Type u) [monad m] [is_lawful_monad m]
198
200
201
+ @[simp]
202
+ lemma mfoldl.unop_of_free_monoid (f : β → α → m β) (xs : free_monoid α) (a : β) :
203
+ unop (mfoldl.of_free_monoid f xs) a = list.mfoldl f a xs := rfl
204
+
199
205
instance fold_mfoldl (f : β → α → m β) :
200
206
is_monoid_hom (mfoldl.of_free_monoid f) :=
201
207
{ map_one := rfl,
202
- map_mul := by { intros, unfold_projs, simp only [mfoldl.of_free_monoid,flip, list.mfoldl_append] } }
203
-
204
- @[simp]
205
- lemma mfoldr.unop_of_free_monoid (f : α → β → m β) (xs : free_monoid α) (a : β) :
206
- unop (mfoldr.of_free_monoid f xs) a = list.mfoldr f a xs := rfl
208
+ map_mul := by intros; apply unop_inj; ext; apply list.mfoldl_append }
207
209
208
210
instance fold_mfoldr (f : α → β → m β) :
209
211
is_monoid_hom (mfoldr.of_free_monoid f) :=
210
212
{ map_one := rfl,
211
- map_mul := by { intros, apply unop_inj, ext, simp only [list.mfoldr_append, mfoldr.unop_of_free_monoid, free_add_monoid.add_def],
212
- apply bind_ext_congr, simp only [mfoldr.unop_of_free_monoid, eq_self_iff_true, forall_true_iff], } }
213
+ map_mul := by intros; ext; apply list.mfoldr_append }
213
214
214
215
variables {t : Type u → Type u} [traversable t] [is_lawful_traversable t]
215
216
open is_lawful_traversable
@@ -254,11 +255,11 @@ lemma foldr.of_free_monoid_comp_free_mk (f : β → α → α) : foldr.of_free_m
254
255
255
256
@[simp]
256
257
lemma mfoldl.of_free_monoid_comp_free_mk {m} [monad m] [is_lawful_monad m] (f : α → β → m α) : mfoldl.of_free_monoid f ∘ free.mk = mfoldl.mk ∘ flip f :=
257
- by { ext, simp only [(∘), mfoldl.of_free_monoid, mfoldl.mk, flip, fold_mfoldl_cons] }
258
+ by ext; simp only [(∘), mfoldl.of_free_monoid, mfoldl.mk, flip, fold_mfoldl_cons]; refl
258
259
259
260
@[simp]
260
261
lemma mfoldr.of_free_monoid_comp_free_mk {m} [monad m] [is_lawful_monad m] (f : β → α → m α) : mfoldr.of_free_monoid f ∘ free.mk = mfoldr.mk ∘ f :=
261
- by { ext, apply unop_inj, simp only [(∘),mfoldr.of_free_monoid,mfoldr.mk,flip,fold_mfoldr_cons] }
262
+ by { ext, simp only [(∘), mfoldr.of_free_monoid, mfoldr.mk, flip, fold_mfoldr_cons] }
262
263
263
264
lemma to_list_spec (xs : t α) :
264
265
to_list xs = (fold_map free.mk xs : free_monoid _) :=
@@ -267,25 +268,27 @@ calc fold_map free.mk xs
267
268
= (fold_map free.mk xs).reverse.reverse : by simp only [list.reverse_reverse]
268
269
... = (list.foldr cons [] (fold_map free.mk xs).reverse).reverse
269
270
: by simp only [list.foldr_eta]
270
- ... = (foldl.of_free_monoid (flip cons) (fold_map free.mk xs) []).reverse
271
- : by simp only [flip,list.foldr_reverse,foldl.of_free_monoid]
272
- ... = to_list xs : by { rw fold_map_hom_free (foldl.of_free_monoid (flip cons)),
273
- simp only [to_list, foldl, list.reverse_inj, foldl.of_free_monoid_comp_free_mk],
274
- all_goals { apply_instance } }
271
+ ... = (unop (foldl.of_free_monoid (flip cons) (fold_map free.mk xs)) []).reverse
272
+ : by simp only [flip,list.foldr_reverse,foldl.of_free_monoid, unop_op]
273
+ ... = to_list xs : begin
274
+ rw fold_map_hom_free (foldl.of_free_monoid (flip cons)),
275
+ simp only [to_list, foldl, list.reverse_inj, foldl.get, foldl.of_free_monoid_comp_free_mk],
276
+ all_goals { apply_instance }
277
+ end
275
278
276
279
lemma fold_map_map [monoid γ] (f : α → β) (g : β → γ) (xs : t α) :
277
280
fold_map g (f <$> xs) = fold_map (g ∘ f) xs :=
278
281
by simp only [fold_map,traverse_map]
279
282
280
283
lemma foldl_to_list (f : α → β → α) (xs : t β) (x : α) :
281
284
foldl f x xs = list.foldl f x (to_list xs) :=
282
- by { change _ = foldl.of_free_monoid _ _ _ ,
283
- simp only [foldl, to_list_spec, fold_map_hom_free (foldl.of_free_monoid f), foldl.of_free_monoid_comp_free_mk] }
285
+ by { rw ← foldl.unop_of_free_monoid ,
286
+ simp only [foldl, to_list_spec, fold_map_hom_free (foldl.of_free_monoid f), foldl.of_free_monoid_comp_free_mk, foldl.get ] }
284
287
285
288
lemma foldr_to_list (f : α → β → β) (xs : t α) (x : β) :
286
289
foldr f x xs = list.foldr f x (to_list xs) :=
287
- by { rw ← foldr.unop_of_free_monoid ,
288
- simp only [foldr, to_list_spec, fold_map_hom_free (foldr.of_free_monoid f), foldr.of_free_monoid_comp_free_mk] }
290
+ by { change _ = foldr.of_free_monoid _ _ _ ,
291
+ simp only [foldr, to_list_spec, fold_map_hom_free (foldr.of_free_monoid f), foldr.of_free_monoid_comp_free_mk, foldr.get ] }
289
292
290
293
lemma to_list_map (f : α → β) (xs : t α) :
291
294
to_list (f <$> xs) = f <$> to_list xs :=
@@ -330,13 +333,13 @@ variables {m : Type u → Type u} [monad m] [is_lawful_monad m]
330
333
331
334
lemma mfoldl_to_list {f : α → β → m α} {x : α} {xs : t β} :
332
335
mfoldl f x xs = list.mfoldl f x (to_list xs) :=
333
- by { change _ = mfoldl.of_free_monoid f (to_list xs) x,
334
- simp only [mfoldl, to_list_spec, fold_map_hom_free (mfoldl.of_free_monoid f),mfoldl.of_free_monoid_comp_free_mk] }
336
+ by { change _ = unop ( mfoldl.of_free_monoid f (to_list xs) ) x,
337
+ simp only [mfoldl, to_list_spec, fold_map_hom_free (mfoldl.of_free_monoid f), mfoldl.of_free_monoid_comp_free_mk, mfoldl.get ] }
335
338
336
339
lemma mfoldr_to_list (f : α → β → m β) (x : β) (xs : t α) :
337
340
mfoldr f x xs = list.mfoldr f x (to_list xs) :=
338
- by { change _ = unop ( mfoldr.of_free_monoid f (to_list xs) ) x,
339
- simp only [mfoldr, to_list_spec, fold_map_hom_free (mfoldr.of_free_monoid f),mfoldr.of_free_monoid_comp_free_mk] }
341
+ by { change _ = mfoldr.of_free_monoid f (to_list xs) x,
342
+ simp only [mfoldr, to_list_spec, fold_map_hom_free (mfoldr.of_free_monoid f), mfoldr.of_free_monoid_comp_free_mk, mfoldr.get ] }
340
343
341
344
@[simp] theorem mfoldl_map (g : β → γ) (f : α → γ → m α) (a : α) (l : t β) :
342
345
mfoldl f a (g <$> l) = mfoldl (λ x y, f x (g y)) a l :=
0 commit comments