forked from DSLsofMath/DSLsofMath
-
Notifications
You must be signed in to change notification settings - Fork 0
/
E1.lhs
280 lines (251 loc) · 7.31 KB
/
E1.lhs
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
\newpage
\section{Exercises: Haskell, DSLs and expressions}
\label{sec:ch1ex}
%include E1_1.lhs
%include E1_2.lhs
\begin{exercise}\label{exc:counting}\textbf{[Important]}
Counting values.
%
Assume we have three finite types |a|, |b|, |c| with cardinalities
|A|, |B|, and |C|.
%
(For example, the \addtoindex{cardinality} of |Bool| is |2|, the cardinality of
|Weekday| is |7|, etc.)
%
Then what is the cardinality of the types |Either a b|? |(a, b)|? |a->b|? etc.
%
\index{Either@@|Either| type}%
\index{pair type}%
\index{function type}%
%
These rules for computing the cardinality suggests that |Either| is
similar to sum, |(,)| is similar to product and |(->)| to (flipped)
power.
%
These rules show that we can use many intuitions from high-school
algebra when working with types.
\end{exercise}
\begin{exercise}{Counting |Maybe|s.} For each of the following types, enumerate and
count the values:
\index{Maybe@@|Maybe| type}%
\begin{enumerate}
\item |Bool -> Maybe Bool|
\item |Maybe Bool -> Bool|
\item |Maybe (Bool, Maybe (Bool, Maybe Bool))|
\end{enumerate}
%
This is an opportunity to practice the learning outcome ``develop
adequate notation for mathematical concepts'': what is a suitable
notation for values of type |Bool|, |Maybe a|, |a->b|, |(a,b)|, etc.?
%
%TODO: Solve in the book to show ``suitable notation''. But then also remove as recommended hand-in exercise.
%
For those interested, \citet{DBLP:conf/haskell/DuregardJW12} present
a Haskell library
(\href{https://hackage.haskell.org/package/testing-feat}{\texttt{testing-feat}})
for enumerating syntax trees.
\end{exercise}
\begin{exercise}\label{exc:funtupE1}
Functions as tuples.
\index{pair type}%
\index{function type}%
\index{Bool@@|Bool| (|BB|)}%
%
For any type |t| the type |Bool -> t| is basically ``the same'' as
the type |(t,t)|.
%
Implement the two functions |isoR| and |isoL| forming an
\addtoindex{isomorphism}:
%
\begin{spec}
isoR :: (Bool -> t) -> (t, t)
isoL :: (t, t) -> (Bool -> t)
\end{spec}
%
and show that |isoL . isoR = id| and |isoR . isoL = id|.
% TODO: place this code in a list of solutions somewhere
% isoR f = (f False, f True)
% isoL (fa, tr) = \b-> case b of {False -> fa; True -> tr}
% Proof:
% LHS1
% =
% isoL . isoR
% =
% \f -> isoL (isoR f)
% =
% \f -> isoL (f False, f True)
% =
% \f -> \b-> case b of {False -> f False; True -> f True}
% Now we have two cases:
% LHS1 f False
% =
% case False of {False -> f False; True -> f True}
% =
% f False
% =
% id f False
% =
% RHS1 f False
% ... and a very similar case for LHS1 f True
% Next law: |isoR . isoL = id|
% LHS2
% =
% isoR . isoL
% =
% \(x, y) -> isoR (isoL (x, y))
% =
% \(x, y) -> isoR (\b-> case b of {False -> x; True -> y})
% =
% \(x, y) -> let f = \b-> case b of {False -> x; True -> y} in (f False, f True)
% =
% \(x, y) -> (x, y)
% =
% id
% TODO: example: which function represents the pair (7, 3)?
% Answer: f False = 7; f True = 3
\end{exercise}
\begin{exercise}\label{exc:tuplingE1}\textbf{[Important]}
Functions and pairs (the ``\addtoindex{tupling transform}'').
%
From one function |f :: a -> (b, c)| returning a pair, you can
always make a pair of two functions |pf :: (a->b, a->c)|.
%
\index{pair type}%
\index{function type}%
%
Implement this transform:
%
\begin{spec}
f2p :: (a -> (b, c)) -> (a->b, a->c)
\end{spec}
%
Also implement the opposite transform:
\begin{spec}
p2f :: (a->b, a->c) -> (a -> (b, c))
\end{spec}
This kind of transformation is often useful, and it works also for
|n|-tuples.
% Solutions:
% f2p = \fg -> (fst . fg, snd . fg)
% p2f = \(f,g) -> \x -> (f x, g x)
\end{exercise}
\begin{exercise}
There is also a ``dual'' to the tupling transform: to show this,
implement these functions:
%
\index{Either@@|Either| type}%
\index{pair type}%
\index{function type}%
%
\begin{spec}
s2p :: (Either b c -> a) -> (b->a, c->a)
p2s :: (b->a, c->a) -> (Either b c -> a)
\end{spec}
\end{exercise}
\begin{exercise}\label{exc:fmap}
From \refSec{sec:infseq}:
%
\begin{itemize}
\index{function composition (|.|)}%
\item What does function composition do to a \addtoindex{sequence}?
%
More concretely: for a sequence |a| what is |a . (1+)|?
%
What is |(1+) . a|?
%(composition on the left?, on the right?)
\item How is |liftSeq1| related to |fmap|? |liftSeq0| to |conSeq|?
\end{itemize}
%
\end{exercise}
\begin{exercise}
Operator sections.
%
\index{operator section}%
%
Please fill out the remaining parts of this table with simplified
expressions:
%
\begin{align*}
|(1+)| &= |\x->1+x| \\
|(*2)| &= |\x->x*2| \\
|(1+).(*2)| &= \\
|(*2).(1+)| &= \\
&= |\x->x^2+1| \\
&= |\x->(x+1)^2| \\
|(a+).(b+)| &= \\
\end{align*}
% Sections, flip, (.), and friends
\end{exercise}
%
\begin{exercise}
Read the full chapter and complete the definition of the
instance for |Num| for the datatype |ComplexSyn|.
%
Also add a constructor for variables to enable writing expressions
like |(Var "z") :*: toComplexSyn 1|.
\end{exercise}
% \begin{exercise}
% TODO: formulate exercise to implement more efficient |show| using an
% accumulating parameter.
% \end{exercise}
\begin{exercise}
\label{exc:embedeval}
%if False
\begin{code}
import DSLsofMath.ComplexSyn
import DSLsofMath.CSem (Complex(C))
\end{code}
%endif
We can embed semantic complex numbers in the syntax:
%
\begin{code}
embed :: Complex r -> ComplexSyn r
embed (C (x, y)) = ToComplexCart x y
\end{code}
%
The embedding should satisfy a round-trip property:
%
|eval (embed s) == s| for all semantic complex numbers |s|.
%
What about the opposite direction: when is |embed (eval e) == e|?
%
Here is a diagram showing how the types and the functions fit together
\hspace{\mathindent}%
\begin{tikzcd}
|ComplexSyn r| \arrow[d, bend left, "|eval|"] \arrow[loop right, "|embed . eval|"] \\
|ComplexSem r| \arrow[u, bend left, "|embed|"] \arrow[loop right, "|eval . embed|"]
\end{tikzcd}
Step 0: type the quantification: what is the type of |e|?
Step 1: what equality is suitable for this type?
Step 2: if you use ``equality up to eval'' --- how is the resulting
property related to the first round-trip property?
%See blackboard/W1/20170116_161148.jpg
\end{exercise}
\begin{exercise}
Read the next few pages of Appendix I (in \citep{adams2010calculus})
defining the polar view of Complex Numbers and try to implement
complex numbers again, this time based on magnitude and phase for
the semantics.
%
Try to use the same interface, so that you can import this new polar
representation or the previous Cartesian representation without
changing anything more than the import statement.
\end{exercise}
\begin{exercise}
Implement a simplifier |simp :: ComplexSyn r -> ComplexSyn r| that
handles a few cases like |0 * x = 0|, |1 * x = x|, |(a + b) * c = a
* c + b * c|, etc.
%
What class context do you need to add to the type of |simp|?
%
This exercise is rather open-ended but it is recommended to start
with a concrete view of what expected ``normal forms'' should be so
that you can test it.
\end{exercise}
%**TODO: include as an early exercise
% Exercises:
% \begin{itemize}
% %*TODO: make this one of the numbered exercises
% \item implement |(*.)| for |ComplexD|
% \end{itemize}
%include E1_from_exams.lhs