diff -r f51e593903ac -r db2a3e3287a9 wsheets/wsh03.tex --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wsheets/wsh03.tex Fri Nov 25 00:03:15 2022 +0000 @@ -0,0 +1,190 @@ +% !TEX program = xelatex +\documentclass{article} +\usepackage{../styles/style} +\usepackage{../styles/langs} +\usepackage{tikz} +\usepackage{pgf} +\usepackage{marvosym} +\usepackage{boxedminipage} + +\lstset{escapeinside={/*!}{!*/}} +\newcommand{\annotation}[1]{\hfill\footnotesize{}#1} + +\usepackage{menukeys} + + +% Exact colors from NB +\usepackage[breakable]{tcolorbox} +\definecolor{incolor}{HTML}{303F9F} +\definecolor{outcolor}{HTML}{D84315} +\definecolor{cellborder}{HTML}{CFCFCF} +\definecolor{cellbackground}{HTML}{F7F7F7} + + + +\begin{document} +\fnote{\copyright{} Christian Urban, King's College London, 2022} + +\section*{Scala Worksheet 3} + + + +\subsection*{Task 1 (Options)} + +Get familiar with the return value of functions that can +``go wrong'': + +\begin{lstlisting}[numbers=none] +scala> List(7,2,3,4,5,6).find(_ < 4) +scala> List(5,6,7,8,9).find(_ < 4) +scala> List(5,6,7,8,9).min +scala> List(5,6,7,8,9).minOption +scala> List[Int]().minOption +\end{lstlisting} + +\noindent +Note that there needs to be a type-annotation for \texttt{List()} otherwise +Scala will not know which \texttt{min}-version it should use. + +\subsection*{Task 2 (Try)} + +The Scala-Idiom \texttt{Try-getOrElse} allows you to conveniently +deal with failure cases. + +\begin{lstlisting}[numbers=none] +scala> Try(Some(List(5,6,7,8,9).min)).getOrElse(None) +scala> Try(Some(List[Int]().min)).getOrElse(None) +\end{lstlisting} + +\noindent +Note that \texttt{Try} needs the library \texttt{scala.util.\_} to be +imported. + + +\begin{lstlisting}[numbers=none] +def safe_div(x: Int, y: Int) : Option[Int] = + Try(Some(x / y)).getOrElse(None) +\end{lstlisting} + +\subsection*{Task 3 (URLs / Files)} + +For simple tasks such as reading webpages and files, Scala provides +convenient functions \texttt{Source.fromURL} and \texttt{Source.fromFile}. +To try them out, you need to import \texttt{io.Source}. + +\begin{lstlisting}[numbers=none] +scala> Source.fromURL(my_url)("ISO-8859-1").mkString +scala> Source.fromFile(my_file)("ISO-8859-1").mkString +\end{lstlisting} + +\noindent +These functions return an iterator, which can be transformed into a String +using \texttt{mkString}. The second argument fixes the character encoding +and should not be omitted. If you are interested in the individual lines +in the file, for example, you can use + +\begin{lstlisting}[numbers=none] +Source.fromFile(my_file)("ISO-8859-1") + .getLines().toList +\end{lstlisting} + +\noindent +If you are after proper error-handling, then you can use Scala's options +as follows + +\begin{lstlisting}[numbers=none] +Try(Some(Source.fromFile("test.txt")("ISO-8859-1") + .mkString)).getOrElse(None) +\end{lstlisting} + +This can also be written slightly shorter as + +\begin{lstlisting}[numbers=none] +Try(Source.fromFile("test.txt")("ISO-8859-1") + .mkString).toOption +\end{lstlisting} + +\noindent +In case of reading files, there can be an issue with closing +files properly. For this Scala provides \texttt{Using} + +\begin{lstlisting}[numbers=none] + Using(Source.fromFile("test.txt")("ISO-8859-1")) + (_.mkString).toOption +\end{lstlisting} + +\noindent +This closes the files automatically after reading, but otherwise +behaves as the code shown above: It gives a \texttt{Some} in the +success case and \texttt{None} in the failure case. However, +\texttt{Using} requires a function as argument for prescribing +of what to do with the file content in the success case. + +\subsection*{Task 4 (Higher-Order Functions)} + +Higher-Order functions means that Scala allows functions to +have functions as arguments and also allows functions to +return functions. Get familiar with the short-hand notation +for simple functions + +\begin{lstlisting}[numbers=none] +scala> List(7,2,3,4,5,6).find(_ < 4) +scala> List(7,2,3,4,5,6).count(_ % 2 == 0) +scala> List(7,2,3,4,5,6).sortWith(_ > _) +scala> List(7,2,3,4,5,6).filter(_ > 4) +\end{lstlisting} + +\noindent +Be aware that this short-hand notation only works for ``smallish'' functions +and that sometimes Scala cannot figure out the types involved without +explicit type annotations. + +\subsection*{Task 5 (Maps)} + +Get familiar with the map-function for lists, sets etc. It is the +quintessential higher-order function and frequently used for transforming +lists. + +\begin{lstlisting}[numbers=none] +scala> List(7,2,3,4,5,6).map(n => n * n) +\end{lstlisting} + +\noindent +Make also sure you see that Scala's \texttt{for}-comprehensions +are just syntactic sugar for \texttt{map}s. What would this +expression look like as \texttt{for}-comprehension? What are +the advantages of \texttt{for}-comprehensions over \texttt{map}s. + + +\subsection*{Task 6 (Pattern-Matching)} + +Rewrite the following function using pattern-matching + +\begin{lstlisting}[numbers=none] +def my_map(lst: List[Int], f: Int => Int) : List[Int] = { + if (lst == Nil) Nil + else f(lst.head) :: my_map(lst.tail, f) +} +\end{lstlisting} + +\noindent +Observe that the type of the function is from \texttt{Int}s to +\texttt{Int}s, which is written in Scala as type \texttt{Int => Int}. + + +\subsection*{Task 7 (Fold, Hard)} + +Implement a function \texttt{fold} for lists of integers. It takes +a list of integers as argument as well as a function $f$ and a unit element $u$. +The function is of type \texttt{(Int, Int) => Int} and the unit element +is an integer. The return type of \texttt{fold} is \texttt{Int}. +What is \texttt{fold} supposed to do? Well it should fold the function $f$ +over the elements of the list and in case of the empty list return the +unit element $u$. + +\end{document} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: t +%%% End: