% !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 2}



\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 (Web-Crawler, Hard)}

Have a look at the web-crawler at the end of \texttt{lecture2.scala}.
Can you modify it such that every page is only visited once? 

\end{document}

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: t
%%% End: 
