29 |
29 |
30 |
30 |
31 |
31 |
32 \subsection*{Task 1 (Options)} |
32 \subsection*{Task 1 (Options)} |
33 |
33 |
34 Get familiar with constructing strings and printing strings |
34 Get familiar with the return value of functions that can |
35 (i.e.~\texttt{println}, \texttt{mkString}, \texttt{toString}, \ldots) |
35 ``go wrong'': |
36 |
36 |
37 \begin{lstlisting}[numbers=none] |
37 \begin{lstlisting}[numbers=none] |
38 scala> List(7,2,3,4,5,6).find(_ < 4) |
38 scala> List(7,2,3,4,5,6).find(_ < 4) |
39 scala> List(5,6,7,8,9).find(_ < 4) |
39 scala> List(5,6,7,8,9).find(_ < 4) |
40 scala> |
40 scala> List(5,6,7,8,9).min |
|
41 scala> List(5,6,7,8,9).minOption |
|
42 scala> List[Int]().minOption |
41 \end{lstlisting} |
43 \end{lstlisting} |
42 |
44 |
43 \subsection*{Task 2 (URLs / Files)} |
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. |
44 |
48 |
45 ALso Try |
49 \subsection*{Task 2 (Try)} |
|
50 |
|
51 The Scala-Idiom \texttt{Try-getOrElse} allows you to conveniently |
|
52 deal with failure cases. |
46 |
53 |
47 \begin{lstlisting}[numbers=none] |
54 \begin{lstlisting}[numbers=none] |
48 scala> |
55 scala> Try(Some(List(5,6,7,8,9).min)).getOrElse(None) |
49 scala> |
56 scala> Try(Some(List[Int]().min)).getOrElse(None) |
50 scala> |
|
51 \end{lstlisting} |
57 \end{lstlisting} |
52 |
58 |
53 \subsection*{Task 3 (Higher-Order Functions)} |
59 \noindent |
|
60 Note that \texttt{Try} needs the library \texttt{scala.util.\_} to be |
|
61 imported. |
54 |
62 |
55 Make sure you understand if-conditions in Scala: They are |
|
56 \emph{expressions}, meaning they need to calculate a result. For |
|
57 example an \texttt{if} without an else-branch is nearly always |
|
58 \emph{not} what you intend to write (because you are not meant to |
|
59 change any ``state'' outside the expression). Also, remember the quirks |
|
60 in Scala with if-conditions needing parentheses and there is no |
|
61 \texttt{then}-keyword. |
|
62 |
63 |
63 \begin{lstlisting}[numbers=none] |
64 \begin{lstlisting}[numbers=none] |
64 scala> val s1 = "foo" |
65 def safe_div(x: Int, y: Int) : Option[Int] = |
65 scala> val s2 = "bar" |
66 Try(Some(x / y)).getOrElse(None) |
66 scala val s3 = "foobar" |
|
67 scala> if (s1 == s2) print("equal") else print("unequal") |
|
68 scala> if (s1 ++ s2 == s3) print("equal") else print("unequal") |
|
69 \end{lstlisting} |
67 \end{lstlisting} |
70 |
68 |
71 \subsection*{Task 4 (Maps)} |
69 \subsection*{Task 3 (URLs / Files)} |
72 |
70 |
73 Write \texttt{for}-comprehensions that enumerate all triples containing the numbers 1 - 5. That is, |
71 For simple tasks such as reading webpages and files, Scala provides |
74 print the list |
72 convenient functions \texttt{Source.fromURL} and \texttt{Source.fromFile}. |
|
73 To try them out, you need to import \texttt{io.Source}. |
75 |
74 |
76 \[ |
75 \begin{lstlisting}[numbers=none] |
77 \texttt{(1,1,1)}, \texttt{(2,1,1)}, \texttt{(3,1,1)} \;\ldots\; \texttt{(5,5,5)} |
76 scala> Source.fromURL(my_url)("ISO-8859-1").mkString |
78 \] |
77 scala> Source.fromFile(my_file)("ISO-8859-1").mkString |
|
78 \end{lstlisting} |
79 |
79 |
80 \noindent |
80 \noindent |
81 Modify the \texttt{for}-comprehensions such that only triples are |
81 These functions return an iterator, which can be transformed into a String |
82 printed where the sum is divisible by 3. Then sort the list according |
82 using \texttt{mkString}. The second argument fixes the character encoding |
83 to the middle element (for this use \texttt{sortBy}). |
83 and should not be omitted. If you are interested in the individual lines |
84 |
84 in the file, for example, you can use |
85 \subsection*{Task 5 (Pattern-Matching)} |
|
86 |
|
87 \subsection*{Task 6 (Web-Crawler)} |
|
88 |
|
89 Write a pretty print function for lists of integers which |
|
90 ``condenses'' elements in the list, meaning if there is a number |
|
91 several times in a row, then print out \mbox{\texttt{n x e}}, where |
|
92 \texttt{n} is the number of repetitions and \texttt{e} is the |
|
93 number. For example |
|
94 |
85 |
95 \begin{lstlisting}[numbers=none] |
86 \begin{lstlisting}[numbers=none] |
96 List(1,1,1,2,3,3) => List(3 x 1, 2, 2 x 3) |
87 Source.fromFile(my_file)("ISO-8859-1") |
97 List(1,2,3,4,4,4) => List(1, 2, 3, 3 x 4) |
88 .getLines().toList |
98 List(1,1,1,1,1,1) => List(6 x 1) |
|
99 List(1,1,1,2,1,1) => List(3 x 1, 2, 2 x 1) |
|
100 \end{lstlisting} |
89 \end{lstlisting} |
101 |
90 |
102 You might like to define a separate function that first counts the occurences |
91 \noindent |
103 for each element and returns a list of (Int, Int)-pairs . |
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 |
|
101 |
|
102 \begin{lstlisting}[numbers=none] |
|
103 Try(Source.fromFile("test.txt")("ISO-8859-1") |
|
104 .mkString).toOption |
|
105 \end{lstlisting} |
|
106 |
|
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} |
|
115 |
|
116 \noindent |
|
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. |
|
122 |
|
123 \subsection*{Task 4 (Higher-Order Functions)} |
|
124 |
|
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 |
|
129 |
|
130 \begin{lstlisting}[numbers=none] |
|
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) |
|
135 \end{lstlisting} |
|
136 |
|
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? |
104 |
179 |
105 \end{document} |
180 \end{document} |
106 |
181 |
107 %%% Local Variables: |
182 %%% Local Variables: |
108 %%% mode: latex |
183 %%% mode: latex |