197
|
1 |
% !TEX program = xelatex
|
123
|
2 |
\documentclass{article}
|
426
|
3 |
\usepackage{../styles/style}
|
|
4 |
\usepackage{../styles/langs}
|
272
|
5 |
\usepackage{tikz}
|
|
6 |
\usepackage{pgf}
|
123
|
7 |
\usepackage{marvosym}
|
184
|
8 |
\usepackage{boxedminipage}
|
123
|
9 |
|
352
|
10 |
\lstset{escapeinside={/*!}{!*/}}
|
|
11 |
\newcommand{\annotation}[1]{\hfill\footnotesize{}#1}
|
272
|
12 |
|
352
|
13 |
\usepackage{menukeys}
|
335
|
14 |
|
|
15 |
|
|
16 |
% Exact colors from NB
|
|
17 |
\usepackage[breakable]{tcolorbox}
|
|
18 |
\definecolor{incolor}{HTML}{303F9F}
|
|
19 |
\definecolor{outcolor}{HTML}{D84315}
|
|
20 |
\definecolor{cellborder}{HTML}{CFCFCF}
|
|
21 |
\definecolor{cellbackground}{HTML}{F7F7F7}
|
334
|
22 |
|
335
|
23 |
|
|
24 |
|
123
|
25 |
\begin{document}
|
442
|
26 |
\fnote{\copyright{} Christian Urban, King's College London, 2022}
|
195
|
27 |
|
445
|
28 |
\section*{Scala Worksheet 2}
|
271
|
29 |
|
444
|
30 |
|
445
|
31 |
|
|
32 |
\subsection*{Task 1 (Options)}
|
444
|
33 |
|
447
|
34 |
Get familiar with the return value of functions that can
|
|
35 |
``go wrong'':
|
301
|
36 |
|
|
37 |
\begin{lstlisting}[numbers=none]
|
445
|
38 |
scala> List(7,2,3,4,5,6).find(_ < 4)
|
|
39 |
scala> List(5,6,7,8,9).find(_ < 4)
|
447
|
40 |
scala> List(5,6,7,8,9).min
|
|
41 |
scala> List(5,6,7,8,9).minOption
|
|
42 |
scala> List[Int]().minOption
|
123
|
43 |
\end{lstlisting}
|
|
44 |
|
447
|
45 |
\noindent
|
|
46 |
Note that there needs to be a type-annotation for \texttt{List()} otherwise
|
|
47 |
Scala will not know which \texttt{min}-version it should use.
|
445
|
48 |
|
447
|
49 |
\subsection*{Task 2 (Try)}
|
|
50 |
|
|
51 |
The Scala-Idiom \texttt{Try-getOrElse} allows you to conveniently
|
|
52 |
deal with failure cases.
|
444
|
53 |
|
445
|
54 |
\begin{lstlisting}[numbers=none]
|
447
|
55 |
scala> Try(Some(List(5,6,7,8,9).min)).getOrElse(None)
|
|
56 |
scala> Try(Some(List[Int]().min)).getOrElse(None)
|
445
|
57 |
\end{lstlisting}
|
444
|
58 |
|
447
|
59 |
\noindent
|
|
60 |
Note that \texttt{Try} needs the library \texttt{scala.util.\_} to be
|
|
61 |
imported.
|
444
|
62 |
|
|
63 |
|
442
|
64 |
\begin{lstlisting}[numbers=none]
|
447
|
65 |
def safe_div(x: Int, y: Int) : Option[Int] =
|
|
66 |
Try(Some(x / y)).getOrElse(None)
|
|
67 |
\end{lstlisting}
|
|
68 |
|
|
69 |
\subsection*{Task 3 (URLs / Files)}
|
|
70 |
|
|
71 |
For simple tasks such as reading webpages and files, Scala provides
|
|
72 |
convenient functions \texttt{Source.fromURL} and \texttt{Source.fromFile}.
|
|
73 |
To try them out, you need to import \texttt{io.Source}.
|
|
74 |
|
|
75 |
\begin{lstlisting}[numbers=none]
|
|
76 |
scala> Source.fromURL(my_url)("ISO-8859-1").mkString
|
|
77 |
scala> Source.fromFile(my_file)("ISO-8859-1").mkString
|
|
78 |
\end{lstlisting}
|
|
79 |
|
|
80 |
\noindent
|
|
81 |
These functions return an iterator, which can be transformed into a String
|
|
82 |
using \texttt{mkString}. The second argument fixes the character encoding
|
|
83 |
and should not be omitted. If you are interested in the individual lines
|
|
84 |
in the file, for example, you can use
|
|
85 |
|
|
86 |
\begin{lstlisting}[numbers=none]
|
|
87 |
Source.fromFile(my_file)("ISO-8859-1")
|
|
88 |
.getLines().toList
|
343
|
89 |
\end{lstlisting}
|
|
90 |
|
447
|
91 |
\noindent
|
|
92 |
If you are after proper error-handling, then you can use Scala's options
|
|
93 |
as follows
|
|
94 |
|
|
95 |
\begin{lstlisting}[numbers=none]
|
|
96 |
Try(Some(Source.fromFile("test.txt")("ISO-8859-1")
|
|
97 |
.mkString)).getOrElse(None)
|
|
98 |
\end{lstlisting}
|
|
99 |
|
|
100 |
This can also be written slightly shorter as
|
444
|
101 |
|
447
|
102 |
\begin{lstlisting}[numbers=none]
|
|
103 |
Try(Source.fromFile("test.txt")("ISO-8859-1")
|
|
104 |
.mkString).toOption
|
|
105 |
\end{lstlisting}
|
444
|
106 |
|
447
|
107 |
\noindent
|
|
108 |
In case of reading files, there can be an issue with closing
|
|
109 |
files properly. For this Scala provides \texttt{Using}
|
|
110 |
|
|
111 |
\begin{lstlisting}[numbers=none]
|
|
112 |
Using(Source.fromFile("test.txt")("ISO-8859-1"))
|
|
113 |
(_.mkString).toOption
|
|
114 |
\end{lstlisting}
|
444
|
115 |
|
|
116 |
\noindent
|
447
|
117 |
This closes the files automatically after reading, but otherwise
|
|
118 |
behaves as the code shown above: It gives a \texttt{Some} in the
|
|
119 |
success case and \texttt{None} in the failure case. However,
|
|
120 |
\texttt{Using} requires a function as argument for prescribing
|
|
121 |
of what to do with the file content in the success case.
|
445
|
122 |
|
447
|
123 |
\subsection*{Task 4 (Higher-Order Functions)}
|
444
|
124 |
|
447
|
125 |
Higher-Order functions means that Scala allows functions to
|
|
126 |
have functions as arguments and also allows functions to
|
|
127 |
return functions. Get familiar with the short-hand notation
|
|
128 |
for simple functions
|
444
|
129 |
|
|
130 |
\begin{lstlisting}[numbers=none]
|
447
|
131 |
scala> List(7,2,3,4,5,6).find(_ < 4)
|
|
132 |
scala> List(7,2,3,4,5,6).count(_ % 2 == 0)
|
|
133 |
scala> List(7,2,3,4,5,6).sortWith(_ > _)
|
|
134 |
scala> List(7,2,3,4,5,6).filter(_ > 4)
|
444
|
135 |
\end{lstlisting}
|
|
136 |
|
447
|
137 |
\noindent
|
|
138 |
Be aware that this short-hand notation only works for ``smallish'' functions
|
|
139 |
and that sometimes Scala cannot figure out the types involved without
|
|
140 |
explicit type annotations.
|
|
141 |
|
|
142 |
\subsection*{Task 5 (Maps)}
|
|
143 |
|
|
144 |
Get familiar with the map-function for lists, sets etc. It is the
|
|
145 |
quintessential higher-order function and frequently used for transforming
|
|
146 |
lists.
|
|
147 |
|
|
148 |
\begin{lstlisting}[numbers=none]
|
|
149 |
scala> List(7,2,3,4,5,6).map(n => n * n)
|
|
150 |
\end{lstlisting}
|
|
151 |
|
|
152 |
\noindent
|
|
153 |
Make also sure you see that Scala's \texttt{for}-comprehensions
|
|
154 |
are just syntactic sugar for \texttt{map}s. What would this
|
|
155 |
expression look like as \texttt{for}-comprehension? What are
|
|
156 |
the advantages of \texttt{for}-comprehensions over \texttt{map}s.
|
|
157 |
|
|
158 |
|
|
159 |
\subsection*{Task 6 (Pattern-Matching)}
|
|
160 |
|
|
161 |
Rewrite the following function using pattern-matching
|
|
162 |
|
|
163 |
\begin{lstlisting}[numbers=none]
|
|
164 |
def my_map(lst: List[Int], f: Int => Int) : List[Int] = {
|
|
165 |
if (lst == Nil) Nil
|
|
166 |
else f(lst.head) :: my_map(lst.tail, f)
|
|
167 |
}
|
|
168 |
\end{lstlisting}
|
|
169 |
|
|
170 |
\noindent
|
|
171 |
Observe that the type of the function is from \texttt{Int}s to
|
|
172 |
\texttt{Int}s, which is written in Scala as type \texttt{Int => Int}.
|
|
173 |
|
|
174 |
|
|
175 |
\subsection*{Task 7 (Web-Crawler, Hard)}
|
|
176 |
|
|
177 |
Have a look at the web-crawler at the end of \texttt{lecture2.scala}.
|
|
178 |
Can you modify it such that every page is only visited once?
|
444
|
179 |
|
123
|
180 |
\end{document}
|
|
181 |
|
|
182 |
%%% Local Variables:
|
|
183 |
%%% mode: latex
|
|
184 |
%%% TeX-master: t
|
|
185 |
%%% End:
|