forked from mbg/uow-exam
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathq5.tex
166 lines (155 loc) · 7.53 KB
/
q5.tex
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
%%% Question 5 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\question This question is about functors, applicative functors, and monads. Consider the following data type definition in Haskell. You may assume that functor, applicative functor, and monad laws have been proved for all instances of the respective type classes except your own. You may \textbf{not} make use of GHC extensions such as \texttt{\small DeriveFunctor}.
\begin{parts}
\part[4] Define suitable instances of the \haskellIn{Functor}, \haskellIn{Applicative}, and \haskellIn{Monad} type classes for \haskellIn{(->) r} (functions whose domain is some type \haskellIn{r}). \emph{Hint}: it may be helpful to write down the specialised type signatures of the type class methods you need to define. \droppoints
\begin{solution} \emph{Application.} 1 mark for the \haskellIn{Functor} instance, 2 marks for the \haskellIn{Applicative} instance, and 1 mark for the \haskellIn{Monad} instance.
\begin{minted}{haskell}
instance Functor ((->) r) where
fmap = (.)
instance Applicative ((->) r) where
pure = const
f <*> g = \x -> f x (g x)
instance Monad ((->) r) where
f >>= k = \x -> k (f x) x
\end{minted}
\end{solution}
\part[13] Prove that your instance of \haskellIn{Applicative} type class for \haskellIn{(->) r} obeys the applicative functor laws. \droppoints
\begin{solution}
\allowdisplaybreaks
\emph{Application.} Identity:
\begin{displaymath}
\begin{array}[]{cl}
\expr{\mathit{pure}~\mathit{id} \applicative v}
\hint{applying $\mathit{pure}$}
\expr{\mathit{const}~\mathit{id} \applicative v}
\hint{applying $\applicative$}
\expr{\lambda x \to \mathit{const}~\mathit{id}~x~(v~x)}
\hint{applying $\mathit{const}$}
\expr{\lambda x \to \mathit{id}~(v~x)}
\hint{applying $\mathit{id}$}
\expr{\lambda x \to v~x}
\hint{$\eta$-conversion}
\lastexpr{v}
\end{array}
\end{displaymath}
Homomorphism:
\begin{displaymath}
\begin{array}[]{cl}
\expr{\mathit{pure}~f \applicative \mathit{pure}~v}
\hint{applying $\mathit{pure}$ twice}
\expr{\mathit{const}~f \applicative \mathit{const}~v}
\hint{applying $\applicative$}
\expr{\lambda x \to \mathit{const}~f~x~(\mathit{const}~v~x)}
\hint{applying $\mathit{const}$ twice}
\expr{\lambda x \to f~v}
\hint{definition of $\mathit{const}$}
\expr{\mathit{const}~(f~v)}
\hint{unapplying $\mathit{pure}$}
\lastexpr{\mathit{pure}~(f~v)}
\end{array}
\end{displaymath}
Interchange:
\begin{displaymath}
\begin{array}[]{cl}
\expr{u \applicative \mathit{pure}~y}
\hint{applying $\applicative$}
\expr{\lambda x \to u~x~(\mathit{pure}~y~x)}
\hint{applying $\mathit{pure}$}
\expr{\lambda x \to u~x~(\mathit{const}~y~x)}
\hint{applying $\mathit{const}$}
\expr{\lambda x \to u~x~y}
\hint{unapplying $\lambda f \to f~y$}
\expr{\lambda x \to (\lambda f \to f~y)~(u~x)}
\hint{unapplying $\$$}
\expr{\lambda x \to (\lambda f \to f~\$~y)~(u~x)}
\hint{syntactic sugar}
\expr{\lambda x \to (\$~y)~(u~x)}
\hint{unapplying $\mathit{const}$}
\expr{\lambda x \to \mathit{const}~(\$~y)~x~(u~x)}
\hint{unapplying $\applicative$}
\expr{\mathit{const}~(\$~y) \applicative u}
\hint{unapplying $\mathit{pure}$}
\lastexpr{\mathit{pure}~(\$~y) \applicative u}
\end{array}
\end{displaymath}
Composition:
\begin{displaymath}
\begin{array}{cl}
\expr{\mathit{pure}~(\circ) \applicative u \applicative v \applicative w}
\hint{applying $\applicative$}
\expr{(\lambda x \to \mathit{pure}~(\circ)~x~(u~x)) \applicative v \applicative w}
\hint{applying $\mathit{pure}$ and $\mathit{const}$}
\expr{(\lambda x \to (\circ)~(u~x)) \applicative v \applicative w}
\hint{applying $\applicative$}
\expr{(\lambda y \to (\lambda x \to (\circ)~(u~x))~y~(v~y)) \applicative w}
\hint{applying function}
\expr{(\lambda y \to (\circ)~(u~y)~(v~y)) \applicative w}
\hint{applying $\applicative$}
\expr{\lambda x \to (\lambda y \to (\circ)~(u~y)~(v~y))~x~(w~x)}
\hint{applying function}
\expr{\lambda x \to (\circ)~(u~x)~(v~x)~(w~x)}
\hint{applying $\circ$}
\expr{\lambda x \to (\lambda y \to u~x~(v~x~y))~(w~x)}
\hint{applying function}
\expr{\lambda x \to u~x~(v~x~(w~x))}
\hint{unapplying function}
\expr{\lambda x \to u~x~((\lambda y \to v~y~(w~y))~x)}
\hint{unapplying $\applicative$}
\expr{\lambda x \to u~x~((v \applicative w)~x)}
\hint{unapplying $\applicative$}
\lastexpr{u \applicative (v \applicative w)}
\end{array}
\end{displaymath}
\end{solution}
\part[8] Prove that your instance of the \texttt{Monad} type class for \haskellIn{(->) r} obeys the monad laws. \droppoints
\begin{solution}
\emph{Application. 2 marks for the left identity. 2 marks for the right identity. 4 marks for associativity.} We can prove left identity through simple equational reasoning to rewrite one side of the equation to the other:
\begin{displaymath}
\begin{array}{cl}
\expr{\mathit{return}~x \bind f}
\hint{Definition of $\mathit{return}$}
\expr{\mathit{const}~x \bind f}
\hint{Definition of $\bind$}
\expr{\lambda r \to f~(\mathit{const}~x~r)~r}
\hint{Applying $\mathit{const}$}
\expr{\lambda r \to f~x~r}
\hint{$\eta$-conversion}
\lastexpr{f~x}
\end{array}
\end{displaymath}
The proof for right identity is also just accomplished through simple, equational reasoning:
\begin{displaymath}
\begin{array}{cl}
\expr{m \bind \mathit{return}}
\hint{Definition of $\bind$}
\expr{\lambda r \to \mathit{return}~(m~r)~r}
\hint{Definition of $\mathit{return}$}
\expr{\lambda r \to \mathit{const}~(m~r)~r}
\hint{Applying $\mathit{const}$}
\expr{\lambda r \to m~r}
\hint{$\eta$-conversion}
\lastexpr{m}
\end{array}
\end{displaymath}
The proof for associativity is also just accomplished through equational reasoning:
\begin{displaymath}
\begin{array}{cl}
\expr{(m \bind f) \bind g}
\hint{Definition of $\bind$}
\expr{(\lambda r \to f~(m~r)~r) \bind g}
\hint{Definition of $\bind$}
\expr{\lambda n \to g~((\lambda r \to f~(m~r)~r)~n)~n}
\hint{$\beta$-reduction}
\expr{\lambda n \to g~(f~(m~n)~n)~n}
\hint{$\beta$-reduction}
\expr{\lambda n \to (\lambda r \to g~(f~(m~n)~r)~r)~n}
\hint{Unapplying $\bind$}
\expr{\lambda n \to (f~(m~n) \bind g)~n}
\hint{$\beta$-reduction}
\expr{\lambda n \to (\lambda x \to f~x \bind g)~(m~n)~n}
\hint{Unapplying $\bind$}
\lastexpr{m \bind (\lambda x \to f~x \bind g)}
\end{array}
\end{displaymath}
\end{solution}
\end{parts}