-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathlec07.txt
More file actions
361 lines (245 loc) · 9.71 KB
/
lec07.txt
File metadata and controls
361 lines (245 loc) · 9.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
Natural transformations
------------------------
Some of the constructions we have seen so far within a category also
apply to CAT.
For example, CAT has an initial object, the empty category, and a
terminal object, the singleton category. CAT has products, C x D, and
coproducts, C + D. Does CAT have exponentials?
We want D^C to have as objects functors C -> D, such that we have a
functor
Apply : D^C x C -> D
Apply (F, X) = F X
The question is: what should the arrows of D^C be so that Apply can be
extended to arrows?
Let alpha : F -> G be an arrow in D^C, and f : X -> Y an arrow in C.
We have
Apply (alpha, f) : Apply (F, X) -> Apply (G, Y)
<=> { action of Apply on objects }
Apply (alpha, f) : F X -> G Y
For any f : X -> Y, alpha should be such that we obtain an arrow F X
-> G Y. It helps to summarize the types of the elements we have so
far:
In C In D
X F X G X
| | |
f | F f | | G f
v v v
Y F Y G Y
To construct the desired diagonal arrow from F X to G Y it would help
to first connect the two "edges" F f and G f to make a square (and
then use a suitable composition of "edges"). This suggests that alpha
: F -> G should fill in _any_ such square in D.
Therefore alpha should be a collection of arrows (in D) of type F X ->
G X, one for every object X (in C).
The collection cannot be arbitrary. Above, we would obtain _two_
arrows of the required type F X -> G Y. Which should we pick? To
avoid having to make an arbitrary choice, we impose instead a
condition on alpha: the two ways should be equal!
Definition: C, D categories, F, G : C -> D functors. A
_transformation_ alpha : F -> G is a mapping from the objects of C to
the arrows of D such that for all X : Obj C
alpha_X : F X -> G X
(it is a standard convention to denote the arrow "alpha X" by
alpha_X).
The arrows alpha_X are sometimes referred to as the _components_ of
the transformation alpha.
A transformation alpha is _natural_ if for all f : X -> Y in C
we have
alpha_Y . F f = G f . alpha_X
alpha_X
X F X ---------> G Y
| | |
f| F f| |G f
| | |
v v alpha_Y v
Y F Y ---------> G Y
Natural transformations compose, and D^C is indeed a category.
Remark: sometimes (for example, in Hinze's articles) the type of a
natural transformation is denoted by an arrow with a dot on the top:
alpha : F --°--> G
I find this irritating, since it obscures the fact that they are the
arrows of categories of functors. (end of remark)
In functional programming, natural transformations correspond to
polymorphic functions.
Examples:
--------
- reverse, flatten, length, append
- arrows given by universal constructions:
1 : Id -> K 1
f : X -> Y
We have:
1 natural transformation
<=> { definition }
1_Y . Id f = K 1 f . 1_X
<=> { Id f = f, K 1 f = id_1 }
1_Y . f = 1_X
<=> { fusion }
true
- fst : (x) -> Fst
(x) : C x C -> C, (x) (X, Y) = X x Y
Fst : C x C -> C, Fst (X, Y) = X
(f, g) : (X1, Y1) -> (X2, Y2)
Fst (f, g) . fst_(X1, Y1) = fst_(X2, Y2) . (f x g)
<=> { definitions }
f . fst_(X1, Y1) = fst_(X2, Y2) .
((f . fst_(X1, Y1)) ^ (g . snd_(X1, Y1))
<=> { cancellation for split }
f . fst_(X1, Y1) = f . fst_(X1, Y1)
<=> { duh }
true
- In the above, we had Fst : C x D -> C, a "polymorphic functor", and
fst : X x Y -> X a natural transformation. Can we view Fst also as
a natural transformation? At this level of generality, no. We
would need Fst to be polymorphic in categories, i.e., to go between
(x) : CAT x CAT -> CAT and FST : CAT x CAT -> CAT; but then (x) and
FST would need to be functors _within_ CAT. To avoid paradoxes, we
would need to introduce various restrictions, such as universes,
etc.
- In Haskell we have
sort :: Ord a => [a] -> [a]
Is this a natural transformation? That depends on the category.
Let TORD be the category of _total_ orders and U the forgetful
functor U : TORD -> Set, U (X, <=) = X.
We have List . U : TORD -> SET, so we would need for any X, Y
preorders and f : X -> Y monotonic function
sort . (List . U) f = (List . U) f . sort
<=> { U f = f, List on arrows is map }
sort . map f = map f . sort
Is it always the case that mapping a _monotonic_ f to a sorted list
gives the same result as sorting the list of the results?
It is. To see this, it suffices to note that sorting two lists
containing the same elements leads to identical results.
- Let TPRE be the category of total preorders and consider the
forgetful functor U : TPRE -> SET, which takes (A, [=) to A. Assume
we have a sorting function
sortP : List X -> List X
which can sort the elements of any total preorder X. Is sort a
natural transformation
sortP : List . U -> List . U
?
The answer is no. Consider a sorting method that preserves the
order of equivalent elements. Consider the preorder (String+, [=)
where non-empty strings are compared only by their first character
in alphabetical order, i.e., (c : cs) [= (c' : cs) iff c comes
before c' in alphabetical order.
The function
f : String+ -> String+
f cs = 'X' : cs
is monotonic w.r.t. [=, since f cs [= f cs' for all cs, cs' (the
monotonicity condition is vacuously satisfied).
Then
sortP (map f ["b", "a"])
= { definition f }
sortP ["Xb", "Xa"]
= { "Xb" ~ "Xa", order is preserved by assumption }
["Xb", "Xa"]
but
map f (sortP ["b", "a"])
= { 'a' comes before 'b' }
map f ["a", "b"]
= { definition f }
["Xa", "Xb"]
Functors and natural transformations
------------------------------------
Let F, G : C -> D and alpha : F -> G.
For any functor H : B -> C we have
alpha_H : F . H -> G . H
(alpha_H)_X = alpha_(H X)
is a natural transformation (_precomposing_ alpha with H).
Similarly, for any functor I : D -> E
I alpha : I . F -> I . G
(I alpha)_X = I (alpha X)
is a natural transformation (_postcomposing_ alpha with I).
Given functors F, G : A -> B and H, I : B -> C, and natural
transformations alpha : F -> G and beta : H -> I, we can define a new
natural transformation
beta * alpha : H . F -> I . G
Writing the types of the elements involved we have
H alpha : H . F -> H . G
I alpha : I . F -> I . G
beta_F : H . F -> I . F
beta_G : H . G -> I . G
We can see we have two choices (for a type correct dep. of *):
beta * alpha = beta_G . H alpha
or
beta * alpha = I alpha . beta_F
Which should we pick?
beta_(G X) . H alpha_X
= { naturality of beta }
I (alpha_X) . beta_(F X)
= { precomposition }
I (alpha_X) . (beta_F)_X
We have used alpha_H for the precomposition, and I alpha for the
postcomposition. In many textbooks, the composition notation is
overloaded: alpha . H and I . alpha would be used, respectively.
This suggests that composition-like properties hold, in particular
associativity:
alpha . G . F = (alpha_G)_F = alpha_(G . F)
I . H . alpha = I (H alpha) = (I . H) alpha
I . alpha . H = (I alpha)_H = I (alpha_H)
and the less obvious
(beta . alpha) . H = (beta . alpha)_H = beta_H . alpha_H
We also have an "abide" law relating . and *:
alpha : F -> G, beta : G -> H, delta : I -> J, gamma : J -> K
(gamma . delta) * (beta . alpha) =
(gamma * beta) . (delta * alpha)
Remark: "abide" comes from "above beside" as in multiplication of
fractions (with · as multiplication):
gamma · delta gamma delta
------------- = ----- · -----
beta · alpha beta alpha
With this comparison, "*" for natural transformations is like division
and "." is multiplication.
(end remark).
Mendler-style folds
-------------------
F endofunctor, initial F-algebra in : F uF -> uF
The universal property of folds states that the equation
x . in = f . F x
has the unique solution x = fold f.
Mendler proposed the following generalisation of folds:
x . in = psi x
where
x : uF -> X
psi : Hom(uF, X) -> Hom(F uF, X)
with the condition that psi be natural in the contravariant argument,
i.e., the X is fixed and
psi : H1 -> H2
H1, H2 : C^op -> Set
H1 Y = Hom(Y, X)
H2 Y = Hom(F Y, X)
for f : Y2 -> Y1 (in C)
H1 f : H1 Y1 -> H1 Y2 (in Set)
H1 f g = g . f
H2 f : H2 Y1 -> H2 Y2 (in Set)
H2 f g = g . F f
The naturality condition gives us for every f : Y2 -> Y1
H2 f . psi_Y1 = psi_Y2 . H1 f
<=> { extensionality (in Set) }
(H2 f . psi_Y1) g = (psi_Y2 . H1 f) g for all g : Y1 -> X
<=> { Composition }
H2 f (psi_Y1 g) = psi_Y2 (H1 f g) for all g : Y1 -> X
<=> { Expand def. of H2 and H1 }
psi_Y1 g . F f = psi_Y2 (g . f) for all g : Y1 -> X
In the case of f with target X, i.e. Y1 = X, we can choose the
identity for g:
f : Y2 -> X
=> { id : X -> X }
psi_X id . F f = psi_Y2 f
Therefore, for f with target X, the action of psi is determined by
psi_X id.
But this is the case of x : uF -> X above! Therefore we have
x . in = psi x
<=> { naturality of psi above }
x . in = psi id . F x
<=> { universal property of fold }
x = fold (psi id)
Therefore, for any natural transformation psi : H1 -> H2, the Mendler
equation has a unique solution, fold (psi id), and therefore Mendler
style folds are not more general than standard folds.
Conversely, for any F-algebra a : F X -> X we can define a natural
transformation
psi : H1 -> H2
psi g = a . F g
and therefore standard folds are also not more general than Mendler
folds.