Browse Source

Add polymorphism section at the beginning

stripped-german
Julian Ospald 9 years ago
parent
commit
db59997841
No known key found for this signature in database GPG Key ID: 220CD1C5BDEED020
1 changed files with 73 additions and 23 deletions
  1. +73
    -23
      VL2.tex

+ 73
- 23
VL2.tex View File

@@ -59,10 +59,60 @@
\end{itemize}
\end{frame}

\section{2. More ways to define functions}
\section{2. Polymorphism}

\begin{frame}[fragile]
\frametitle{2. More ways to define functions}
\frametitle{2. Polymorphism}
So when we said that haskell is good for abstraction, what did we actually mean? Do we have something like java generics or C++ templates?
\vspace{\baselineskip}
\\
\pause
Even better! Haskell supports polymorphism for both data types and functions.\\
Let's start with a polymorphic data type:
\begin{haskellcode}
data List t = Empty | Cons t (List t)
\end{haskellcode}
So we just implemented our own singly-linked List. For any type! Let's use it:
\pause
\begin{haskellcode}
intList :: List Int
intList = Cons 3 (Cons 5 (Cons 2 Empty))

charList :: List Char
charList = Cons 'x' (Cons 'y' (Cons 'z' Empty))

-- whatever you can imagine goes here
\end{haskellcode}
\end{frame}

\begin{frame}[fragile]
\frametitle{2. Polymorphism (ctn.)}
And now we are going to write functions to use it:
\begin{haskellcode}
isListEmpty :: List t -> Bool
isListEmpty Emtpy = True
isListEmpty x = False
\end{haskellcode}
\pause
We can even have more generic stuff like:
\begin{haskellcode}
f :: a -> b
\end{haskellcode}
Whatever the function does... it has something of one type and returns something of another type (\emph{not} the same). That's all we know.
\vspace{\baselineskip}
\\
\pause
Similarly, remember the function \code{head} which gives us the first element of a list? The type signature actually looks like this:
\begin{haskellcode}
head :: [a] -> a
\end{haskellcode}
Makes sense?
\end{frame}

\section{3. More ways to define functions}

\begin{frame}[fragile]
\frametitle{3. More ways to define functions}
Now you know how a regular function looks like, e.g:
\begin{haskellcode}
f :: Int -> Int
@@ -82,10 +132,10 @@ Haskell allows us to \textbf{inline} functions in a few more ways, e.g.:
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}
\subsection{3.1. Where}

\begin{frame}[fragile]
\frametitle{2.1. Where}
\frametitle{3.1. Where}
We use \code{where} to define a helper function:
\begin{haskellcode}
f :: Int -> Int
@@ -95,10 +145,10 @@ f x = x + (y 2)
\end{haskellcode}
\end{frame}

\subsection{2.2. Let}
\subsection{3.2. Let}

\begin{frame}[fragile]
\frametitle{2.2. Let}
\frametitle{3.2. Let}
Another way which is very similar would be using \code{let}:
\begin{haskellcode}
f :: Int -> Int
@@ -107,10 +157,10 @@ f x = let y p = x + p
\end{haskellcode}
\end{frame}

\subsection{2.3. Let vs Where}
\subsection{3.3. Let vs Where}

\begin{frame}[fragile]
\frametitle{2.3. Let vs Where}
\frametitle{3.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
@@ -130,10 +180,10 @@ There are a few more intricacies, but most of the time this is just style consid
How would we have to rewrite the function in order to use \code{let}?
\end{frame}

\subsection{2.4. Anonymous functions}
\subsection{3.4. Anonymous functions}

\begin{frame}[fragile]
\frametitle{2.4. Anonymous functions}
\frametitle{3.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
@@ -148,10 +198,10 @@ f x = x + 1
Anonymous functions will come extremely handy later, you'll see.
\end{frame}

\section{3. Currying}
\section{4. Currying}

\begin{frame}[fragile]
\frametitle{3. Currying}
\frametitle{4. 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}
@@ -168,7 +218,7 @@ which is actually pretty close.
\end{frame}

\begin{frame}[fragile]
\frametitle{3. Currying (ctn.)}
\frametitle{4. 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}
\\
@@ -176,7 +226,7 @@ Let that sink in a little bit and read it again.
\end{frame}

\begin{frame}[fragile]
\frametitle{3. Currying (ctn.)}
\frametitle{4. Currying (ctn.)}
Maybe a mathematical example will make things clearer. Let's say we have the function:\\
$f(x, y) = y / x$
\vspace{\baselineskip}
@@ -198,7 +248,7 @@ $g(3) = f (2, 3) = 3 / 2$
\end{frame}

\begin{frame}[fragile]
\frametitle{3. Currying (ctn.)}
\frametitle{4. 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}
@@ -209,7 +259,7 @@ For every of these steps we can define a real new function. This scales up to an
\end{frame}

\begin{frame}[fragile]
\frametitle{3. Currying (ctn.)}
\frametitle{4. Currying (ctn.)}
So in mathematical terms you can say:\\
$f : A_1 \times ... \times A_n \mapsto B$
\vspace{\baselineskip}
@@ -229,7 +279,7 @@ On the other hand function application is \emph{left}-associative, so \code{f 3
\end{frame}

\begin{frame}[fragile]
\frametitle{3. Currying (ctn.)}
\frametitle{4. 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}
@@ -254,7 +304,7 @@ f = \x -> (\y -> (\z -> ... )) -- right-associative, ofc
\end{frame}

\begin{frame}[fragile]
\frametitle{3. Currying (ctn.)}
\frametitle{4. Currying (ctn.)}
As said in the beginning of this section, these two look pretty similar:
\begin{haskellcode}
f :: Int -> Int -> Int
@@ -269,10 +319,10 @@ uncurry :: (a -> b -> c) -> (a, b) -> c
\end{haskellcode}
\end{frame}

\section{4. Function composition}
\section{5. Function composition}

\begin{frame}[fragile]
\frametitle{4. Function composition}
\frametitle{5. 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}
\\
@@ -297,7 +347,7 @@ composedFunction = f . g
\end{frame}

\begin{frame}[fragile]
\frametitle{4. Function composition}
\frametitle{5. Function composition}
But let's not stop here. What does the dot \code{(.)} actually mean?
\vspace{\baselineskip}
\\
@@ -318,10 +368,10 @@ Solution:
\end{haskellcode}
\end{frame}

\section{5. Recursion patterns}
\section{6. Recursion patterns}

\begin{frame}[fragile]
\frametitle{5. Recursion patterns}
\frametitle{6. 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


Loading…
Cancel
Save