Finished haskell-part

* Notes now is multimarkdown
 * Notes has "checklist"
 * Haskell examples are complete
This commit is contained in:
Oliver Rümpelein 2016-04-21 15:57:27 +02:00
parent 7657c1a493
commit 4110c30cc6
5 changed files with 174 additions and 60 deletions

View file

@ -1,4 +1,12 @@
# WTFunctional: Modifying your WTF-Count using functional programming # Title: WTFunctional: Modifying yout WTF-Count using functional programming
Author: Oliver Rümpelein
html header: <link rel="stylesheet"
href="http://yandex.st/highlightjs/7.3/styles/default.min.css">
<script src="http://yandex.st/highlightjs/7.3/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
# [%title] #
## Content ## ## Content ##
@ -8,24 +16,27 @@
+ functions as first class “objects”: i.e. C++, 5; is a valid statement + functions as first class “objects”: i.e. C++, 5; is a valid statement
+ lambdas + lambdas
+ lists, maps, filters, folds + lists, maps, filters, folds
=> readability, less code reproduction, threadsafety…
+ currying => just convenience + currying => just convenience
+ code example: Pythagoraian triangles. + code example: Pythagoraian triangles, bubble sort
* Phuncy: The pythonic way is functional! * Phuncy: The pythonic way is functional!
+ Not strictly functional - Not strictly functional
+ recursion, fafco - recursion, fafco
+ lambda syntax - lambda syntax
+ map, fold => example (sum of squares?) - map, fold => example (sum of squares?)
- python lambda syntax: lambda a,b: a+b - python lambda syntax: lambda a,b: a+b
- fold with reduce - fold with reduce
- don't return lists, but iterators! - don't return lists, but iterators!
- Note: 2: map, filter, reduce - Note: 2: map, filter, reduce, list comprehension
3: map, filter, functools.reduce() 3: map, filter, functools.reduce(), list comprehension
```Removed reduce(). Use functools.reduce() if you really need it;
however, 99 percent of the time an explicit for loop is more
readable.``` - The python2 to 3 page states:
Why use it? => Multi-processing! “Removed `reduce()`. Use `functools.reduce()` if you really need it;
``` however, 99 percent of the time an explicit `for` loop is more
readable.”
- Why use it? => Multi-processing, WTF Count.
```python
a = list(range(10)) a = list(range(10))
b = 0 b = 0
@ -34,19 +45,20 @@
print(b) print(b)
``` ```
vs. vs.
```
```python
from functools import reduce from functools import reduce
print(reduce(lambda x,y: x+y,map(lambda x: x**2,range(10)))) print(reduce(lambda x,y: x+y,map(lambda x: x**2,range(10))))
``` ```
+ currying: not really, but binding via lambdas or functools.partial() or - currying: not really, but binding via lambdas or functools.partial() or
https://mtomassoli.wordpress.com/2012/03/18/currying-in-python/ https://mtomassoli.wordpress.com/2012/03/18/currying-in-python/
+ decorators! - decorators!
+ still FP, has advantages and is heavily used, i.e. in genomics (works on - still FP has advantages and is heavily used, i.e. in genomics (works on
tons of lengthy lists) tons of lengthy lists)
* FunCtional++: On the fast lane * FunCtional++: On the fast lane
+ "Classical" C++ has some functional stuff, bust i.e. no lambdas (hardly usable) - "Classical" C++ has some functional stuff, bust i.e. no lambdas (hardly usable)
+ Changed with the new C++11-standard - Changed with the new C++11-standard
+ Buzzwords: - Buzzwords:
- `map` defines a Datatype in C++! - `map` defines a Datatype in C++!
- lambdas in C++ - lambdas in C++
```[](int x, int y) { return a<b;} ;``` ```[](int x, int y) { return a<b;} ;```

35
examples/01_haskell.hs Normal file
View file

@ -0,0 +1,35 @@
extract :: [a] -> a
extract [] = error("Too few objects")
extract (x:xs) = x
a = extract [1,2,3,4,5]
addto :: (Num a) => [a] -> a -> [a]
addto [] _ = [] -- edge case (list empty)
addto (x:xs) y = (x+y) : addto xs y
b = [1..4]
-- c == [5,6,7,8]
c = addto b 4
-- d == [25,36,49,64]
d = map (^2) c
-- e == [6,8]
e = filter (\x -> (mod x 2) == 0) c
mfold :: (t -> t1 -> t1) -> t1 -> [t] -> t1
mfold f z [] = z
mfold f z (x:xs) = f x (mfold f z xs)
msum = mfold (+) 0
g = msum [1..100]
pt = [(a,b,c) | a <- [1..15], b <- [1..a], c <- [1..b], a^2 == b^2 + c^2]
bsort :: (t -> t -> Bool) -> [t] -> [t]
bsort f [] = []
bsort f (x:xs) = (bsort f a) ++ [x] ++ (bsort f b)
where a = [ y | y <- xs, not (f x y) ]
b = [ y | y <- xs, (f x y) ]
mbsort = bsort (\x y -> (x < y))
h = [1, 20, -10, 5]
i = mbsort h

View file

@ -1,12 +0,0 @@
extract :: [a] -> a
extract [] = error("Too few objects")
extract (x:xs) = x
a = extract [1,2,3,4,5]
addto :: (Num a) => [a] -> a -> [a]
addto [] _ = [] -- edge case (list empty)
addto (x:xs) y = (x+y) : addto xs y
b = [1..4]
-- c == [5,6,7,8]
c = addto b 4

5
tex/wtf.bib Normal file
View file

@ -0,0 +1,5 @@
@online{whichfold,
title={Foldr Foldl Foldl' - HaskellWiki},
urldate={2016-04-21},
url={https://wiki.haskell.org/Foldr_Foldl_Foldl%27},
}

View file

@ -3,6 +3,8 @@
\usepackage{babel} \usepackage{babel}
\usepackage{csquotes} \usepackage{csquotes}
\usepackage{tabularx} \usepackage{tabularx}
\usepackage[backend=biber, style=numeric,]{biblatex}
\bibliography{wtf}
\usepackage{fontspec} \usepackage{fontspec}
\setsansfont{Fira Sans} \setsansfont{Fira Sans}
@ -97,37 +99,34 @@
\end{frame} \end{frame}
\begin{frame}[fragile]{Syntax Lists (1)} \begin{frame}[fragile]{Syntax Lists (1)}
Lists in Haskell can only hold data of one type. They are defined using \begin{itemize}[<+->]
\haskellcmd{a = [1,2,3,4]} or similar. \item Lists in Haskell can only hold data of one type. They are defined using
\haskellcmd{a = [1,2,3,4]} or similar.
\pause \item An automatic range can be obtained by using \haskellcmd{b = [1..4]},
Furthermore, an automatic range can be obtained by using where the last number is inclusive.
\haskellcmd{b = [1..4]}, where the last number is inclusive. \item If possible, Haskell will try to inhibit the step
automatically. \haskellcmd{c = [1,3..7]} yields
\pause \haskellcmd{[1,3,5,7]}.
If possible, Haskell will try to inhibit the step automatically \item When leaving out the end specifier, a range can be infinite. In this case,
\haskellcmd{c = [1,3..7]} yields \haskellcmd{[1,3,5,7]}. it's up to the programmer to constrain things.
\end{itemize}
\pause
When leaving out the end specifier, a range can be infinite. In this case,
it's up to the programmer to constrain things.
\end{frame} \end{frame}
\begin{frame}[fragile]{Syntax Lists (2)} \begin{frame}[fragile]{Syntax Lists (2)}
Two arrays can be concatenated using the \haskellcmd{++} operator \begin{itemize}[<+->]
\haskellcmd{[1,2,3] ++ [4..7]} \item Two lists can be concatenated using the \haskellcmd{++} operator:
\haskellcmd{[1,2,3] ++ [4..7]}
Single objects get pushed to the front using \haskellcmd{:}: \item Single objects get pushed to the front using
\haskellcmd{1:[2..7]}. \enquote{\haskellcmd{:}}: \haskellcmd{1:[2..7]}.
\item This can also be used vice versa to extract single values from lists:
This can also be used vice versa to extract single values from lists \begin{haskell}
\begin{haskell} extract (x:xs) = x
extract (x:xs) = x -- a = 1
-- a = 1 a = extract [1..5]
a = extract [1..5] \end{haskell}
\end{haskell} \end{itemize}
\end{frame} \end{frame}
\begin{frame}[fragile]{Syntax Recursion} \begin{frame}[fragile]{Syntax Recursion}
Example: Add a value to every entry in an array Example: Add a value to every entry in an array
\begin{haskell} \begin{haskell}
@ -139,8 +138,83 @@
c = addto b 4 c = addto b 4
\end{haskell} \end{haskell}
\end{frame} \end{frame}
\begin{frame}[fragile]{Lambdas}
\begin{itemize}[<+->]
\item By now: lambda-functions well known from other programming languages
\item Represent \enquote{anonymous} functions, i.e. locally defined functions
without associated name
\item Can simply be passed to algorithms, i.e. sort.
\item Syntax: \haskellcmd{\var1 var2 -> retval}
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Maps, Filters}
\begin{itemize}[<+->]
\item A \emph{Map} applies a function to all elements of a list:
\haskellcmd{map (^2) c}\quad (square the elements of c)
\item A \emph{Filter} does exactly that to a list:
\haskellcmd{filter (\x -> (mod x 2) == 0) c} \quad (even numbers in c,
filtering done using a lambda function)
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Folds (1)}
\begin{itemize}[<+->]
\item \emph{Folds} (or sometimes \emph{reductions}) create single values
using whole lists, i.e. sums over all elements
\item Often implemented using recursion
\item Need a function, an initialization value and a list
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Folds (2)}
\uncover<+-> Example: Self written Right fold and sum:
\begin{haskell}
mfold f z [] = z
mfold f z (x:xs) = f x (mfold f z xs)
msum = mfold (+) 0
-- g == 5050
g = msum [1..100]
\end{haskell}
\uncover<+->{Note that this gets pretty resource hungry with large
lists, better use left-folds for this (see~\cite{whichfold})}
\end{frame}
\begin{frame}[fragile]{Example: Pythagorean triangles}
Get all Pythagorean triangles with a hypotenuse off length at most 15:
\begin{haskell}
> [(a,b,c) | a <- [1..15],
b <- [1..a],
c <- [1..b],
a^2 == b^2 + c^2]
[(5,4,3),(10,8,6),(13,12,5),(15,12,9)]
\end{haskell}
\end{frame}
\begin{frame}[fragile]{Example: Bubble-sort}
Recursive, functional bubble-sort algorithm:
\begin{haskell}
bsort f [] = []
bsort f (x:xs) = (bsort f a) ++ [x] ++ (bsort f b)
where a = [ y | y <- xs, not (f x y) ]
b = [ y | y <- xs, (f x y) ]
mbsort = bsort (\x y -> (x > y))
\end{haskell}
\pause Result:
\begin{haskell}
λ> h = [1, 20, -10, 5]
λ> mbsort h
[-10,1,5,29]
\end{haskell}
\end{frame}
\begin{frame}[plain]{References}
\printbibliography
\end{frame}
\end{document} \end{document}
%%% Local Variables: %%% Local Variables:
%%% mode: latex %%% mode: latex
%%% ispell-dictionary: en
%%% End: %%% End: