diff --git a/VL2.tex b/VL2.tex new file mode 100644 index 0000000..73db639 --- /dev/null +++ b/VL2.tex @@ -0,0 +1,352 @@ +\documentclass[10pt,a5paper,mathserif,serif,usenames,dvipsnames]{beamer} + +% packages +\usepackage{xcolor} +\usepackage[utf8]{inputenc} +\usepackage{amsmath} +\usepackage{amsfonts} +\usepackage{amssymb} +\usepackage{graphicx} +\usepackage{listings} +\usepackage{minted} + +% for \verb inside \item +\usepackage[T1]{fontenc} +\usepackage[Q=yes]{examplep} + +% package configuration +\DeclareGraphicsExtensions{.pdf,.png,.jpg} +\beamertemplatenavigationsymbolsempty +\setbeamertemplate{footline}[frame number] +\usemintedstyle{friendly} +\newminted{haskell}{frame=single,numbers=left} +\newminted{cpp}{frame=single,numbers=left} +\newminted{c}{frame=single,numbers=left} +\renewcommand{\theFancyVerbLine}{\ttfamily + \textcolor[rgb]{0.0,0.0,0.0}{\footnotesize + \oldstylenums{\arabic{FancyVerbLine}}}} + +% title page information +\author{Julian Ospald} +\institute{FH Bielefeld} +\title{Haskell: higher order functions} + +% color definition +\definecolor{solarized}{HTML}{002B36} +\definecolor{mygreen}{rgb}{0,0.6,0} + +% macros and environments +\newcommand{\code}[1]{\texttt{#1}} + +\begin{document} + +\frame{\titlepage} + +\begin{frame}[allowframebreaks=0.8] +\frametitle{Table of Contents} +\tableofcontents +\end{frame} + +\section{1. Reiteration} + +\begin{frame} +\frametitle{1. Reiteration} +\begin{itemize} +\item What is haskell? What are the 3 fundamental concepts behind it? +\item How do you do pattern matching? +\item What is the difference between lists and tuples? How do you construct them? +\item How do you define your own data types? +\end{itemize} +\end{frame} + +\section{2. More ways to define functions} + +\begin{frame}[fragile] +\frametitle{2. More ways to define functions} +Now you know how a regular function looks like, e.g: +\begin{haskellcode} +f :: Int -> Int +f x = x + 1 +\end{haskellcode} +But now imagine we need a helper function which is very specific to the current function. In C we would have to define this new helper function at top-level and would probably make it \code{static}. +\pause +\vspace{\baselineskip} +\\ +Haskell allows us to \textbf{inline} functions in a few more ways, e.g.: +\begin{itemize}[<+->] +\item with \code{where} +\item with \code{let...in} +\item anonymously (lambda abstraction) +\end{itemize} +\onslide<+-> +A lot of Haskellers really dislike if you put non-generic functions at the top level. So you can still have atomic pieces, but inline the parts which are very specific to the current function. +\end{frame} + +\subsection{2.1. Where} + +\begin{frame}[fragile] +\frametitle{2.1. Where} +We use \code{where} to define a helper function: +\begin{haskellcode} +f :: Int -> Int +f x = x + (y 2) + where + y p = x + p +\end{haskellcode} +\end{frame} + +\subsection{2.2. Let} + +\begin{frame}[fragile] +\frametitle{2.2. Let} +Another way which is very similar would be using \code{let}: +\begin{haskellcode} +f :: Int -> Int +f x = let y p = x + p + in x + (y 2) +\end{haskellcode} +\end{frame} + +\subsection{2.3. Let vs Where} + +\begin{frame}[fragile] +\frametitle{2.3. Let vs Where} +These look almost the same, but they are different constructs. \code{where} is bound to the pattern matching \code{f x =} and may also have access to parts of a function that are not syntactically expressions, e.g.: +\begin{haskellcode} +f x + | cond1 x = a + | cond2 x = g a + | otherwise = f (h x a) + where + a = w x +\end{haskellcode} +While that is not possible with \code{let} which is an actual expression and can be used whenever expressions are allowed (e.g. inside \emph{Monads}, we'll know more about these in a few weeks). +\vspace{\baselineskip} +\\ +There are a few more intricacies, but most of the time this is just style consideration:\\ \url{https://wiki.haskell.org/Let_vs._Where} +\pause +\vspace{\baselineskip} +\\ +How would we have to rewrite the function in order to use \code{let}? +\end{frame} + +\subsection{2.4. Anonymous functions} + +\begin{frame}[fragile] +\frametitle{2.4. Anonymous functions} +We can also have \textbf{anonymous functions} which just means the function doesn't have a name: +\begin{haskellcode} +f :: Int -> Int +f x = (\y -> y + 1) x +\end{haskellcode} +\pause +Although this is basically the same as: +\begin{haskellcode} +f :: Int -> Int +f x = x + 1 +\end{haskellcode} +Anonymous functions will come extremely handy later, you'll see. +\end{frame} + +\section{3. Currying} + +\begin{frame}[fragile] +\frametitle{3. Currying} +This is what actually makes haskell such a fine functional language. You might have noticed that I tried hard to not show type signatures of functions that have more than one argument. Well, that's because we have to dig a little deeper to explain what comes next: +\pause +\begin{haskellcode} +addInt :: Int -> Int -> Int +addInt x y = x + y +\end{haskellcode} +\pause +So, what is happening here? You probably expected something like: +\begin{haskellcode} +addInt :: (Int, Int) -> Int +addInt (x, y) = x + y +\end{haskellcode} +which is actually pretty close. +\end{frame} + +\begin{frame}[fragile] +\frametitle{3. Currying (ctn.)} +Currying is actually a mathematical thing and is the technique of translating the evaluation of a function that takes multiple arguments (or a tuple) into evaluating a sequence of functions, each with a single argument. +\vspace{\baselineskip} +\\ +Let that sink in a little bit and read it again. +\end{frame} + +\begin{frame}[fragile] +\frametitle{3. Currying (ctn.)} +Maybe a mathematical example will make things clearer. Let's say we have the function:\\ +$f(x, y) = y / x$ +\vspace{\baselineskip} +\\ +\pause +In order to evaluate the function for $x = 2$ and $y = 3$ we would do:\\ +$f(2, 3) = 2 / 3$\\ +and be done. +\vspace{\baselineskip} +\\ +\pause +However, how about we just put in x first and make a new function. Since x is gone, we can write:\\ +$g(y) = f(2, y) = y / 2$ +\vspace{\baselineskip} +\\ +\pause +And in a second step we solve the function $g(y)$:\\ +$g(3) = f (2, 3) = 3 / 2$ +\end{frame} + +\begin{frame}[fragile] +\frametitle{3. Currying (ctn.)} +You can also imagine this geometrically:\\ +$z = f(x, y)$ is 3-dimensional. If you fix the variable $x$ you'll make things 2-dimensional (the intersecting plane). If you then fix $y$ you'll get an actual point $z$. +\vspace{\baselineskip} +\\ +\includegraphics*[scale=0.4]{Grafico_3d_x2+xy+y2.png} +\\ +For every of these steps we can define a real new function. This scales up to any number of dimensions/arguments. +\end{frame} + +\begin{frame}[fragile] +\frametitle{3. Currying (ctn.)} +So in mathematical terms you can say:\\ +$f : A_1 \times ... \times A_n \mapsto B$ +\vspace{\baselineskip} +\\ +gets modified into:\\ +\pause +$f' : A_1 \mapsto (A_2 \mapsto (\ ...\ (A_n \mapsto B)))$ +\vspace{\baselineskip} +\\ +\pause +Did you just notice the braces? They are \textbf{very} important! So, currying is \emph{right}-associative which means that these two signatures are equivalent: +\begin{haskellcode} +f :: Int -> Int -> Int +f :: Int -> (Int -> Int) +\end{haskellcode} +On the other hand function application is \emph{left}-associative, so \code{f 3 2} is just a shorthand of \code{(f 3) 2}. Makes sense? +\end{frame} + +\begin{frame}[fragile] +\frametitle{3. Currying (ctn.)} +What does that mean for us? It's not just fun stuff or aesthetic. It allows us to do \textbf{partial application}. That means we do not have to give a function all arguments. If we pass an "insufficient" number of arguments it will just give us a new function! Here: +\pause +\begin{haskellcode} +addInt :: Int -> Int -> Int +addInt x y = x + y + +addTwo :: Int -> Int +addTwo = addInt 2 +\end{haskellcode} +You probably noticed that we did not write \code{addTwo x = ...}, but why would we? We gave \code{addInt} one argument, so the arity (we called it dimension in the gemoetrical example) is one less, but there is still one parameter left we can pass in. +\vspace{\baselineskip} +\\ +\pause +The reason we can omit the \code{x} here is that +\begin{haskellcode} +f x y z = ... +\end{haskellcode} +is just syntax sugar for +\begin{haskellcode} +f = \x -> (\y -> (\z -> ... )) -- right-associative, ofc +\end{haskellcode} +\end{frame} + +\begin{frame}[fragile] +\frametitle{3. Currying (ctn.)} +As said in the beginning of this section, these two look pretty similar: +\begin{haskellcode} +f :: Int -> Int -> Int + +f :: (Int, Int) -> Int +\end{haskellcode} +And we now know that we can convert from one to another. Of course haskell also provides us two functions to do that, here we go: +\begin{haskellcode} +curry :: ((a, b) -> c) -> a -> b -> c + +uncurry :: (a -> b -> c) -> (a, b) -> c +\end{haskellcode} +\end{frame} + +\section{4. Function composition} + +\begin{frame}[fragile] +\frametitle{4. Function composition} +So why did we just bother so long with explaining currying? It's because it's very important for function composition. Which again is also one of the fundamental concepts of functional programming. +\vspace{\baselineskip} +\\ +From maths we already know that:\\ +$(g \circ f)(x) = g(f(x))$ +\vspace{\baselineskip} +\\ +\pause +And that's basically it. We do the same in haskell, it looks like this: +\begin{haskellcode} +composedFunction x = (f . g) x + +-- same as above... everything on the right side of $ +-- is evaluated first +composedFunction x = f . g $ x + +-- and same again, remember that 'f x =' +-- is just syntax sugar +-- omitting the x here is also called eta reduction +composedFunction = f . g +\end{haskellcode} +\end{frame} + +\begin{frame}[fragile] +\frametitle{4. Function composition} +But let's not stop here. What does the dot \code{(.)} actually mean? +\vspace{\baselineskip} +\\ +\pause +It's just a function (the \emph{prefix} version of \code{.})! Here is the type signature: +\begin{haskellcode} +(.) :: (b -> c) -> (a -> b) -> a -> c +\end{haskellcode} +\pause +\textbf{Exercise:} Implement it! It's really just one line! Remember the mathematical definition. +\vspace{\baselineskip} +\\ +\pause +Solution: +\begin{haskellcode} +(.) :: (b -> c) -> (a -> b) -> a -> c +(.) f g x = f (g x) +\end{haskellcode} +\end{frame} + +\section{5. Recursion patterns} + +\begin{frame}[fragile] +\frametitle{5. Recursion patterns} +Since we use lists a lot in haskell, we also want some more powerful functions to deal with them. E.g.: +\begin{itemize} +\item perform an operation on every element on a list +\item keep only some elements in the list, following some criteria +\item "summarize" the elements of the list somehow +\item ... +\end{itemize} +\pause +How do we do that? Let's say we have a list of \code{Int} and want to add \code{2} to every element of the list. +\begin{haskellcode} +addTwo :: [Int] -> [Int] +addTwo ... ? +\end{haskellcode} +\pause +\textbf{Exercise:} Find the answer! 5 minutes time, remember the \emph{cons} operator \code{(:)}, pattern matching on lists and ofc recursion! Start with the case of an empty list. +\end{frame} + +\begin{frame}[fragile] +\frametitle{5. Recursion patterns (ctn.)} +Solution? +\begin{haskellcode} +addTwo :: [Int] -> [Int] +addTwo [] = [] +addTwo (x:xs) = (x + 2) : addTwo xs +\end{haskellcode} +\end{frame} + +\end{document} \ No newline at end of file