Finished haskell-part
* Notes now is multimarkdown * Notes has "checklist" * Haskell examples are complete
This commit is contained in:
parent
7657c1a493
commit
4110c30cc6
5 changed files with 174 additions and 60 deletions
54
Notes.md
54
Notes.md
|
@ -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
35
examples/01_haskell.hs
Normal 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
|
|
@ -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
5
tex/wtf.bib
Normal 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},
|
||||||
|
}
|
|
@ -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:
|
Loading…
Reference in a new issue