Commit 1a65de6a authored by Max Voit's avatar Max Voit
Browse files

restructured recusion/ higher order tools, stack

parent b92bcbb0
%% Cell type:markdown id: tags:
# lists and tuples
## fun with lists
a list is a finite, ordered set
- [] brackets define lists
[1,2,3,4,5]
- list-elements must be of the same type
%% Cell type:code id: tags:
``` haskell
:option no-lint
[1,2,3.2]
```
%%%% Output: display_data
%% Cell type:code id: tags:
``` haskell
['a','b']
```
%%%% Output: display_data
%% Cell type:code id: tags:
``` haskell
[1,2,'a']
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
## Ranges
- from...to (ranges) (be careful with floating points because of rounding errors)
%% Cell type:code id: tags:
``` haskell
[1,3..8]
```
%%%% Output: display_data
%% Cell type:code id: tags:
``` haskell
['a'..'z']
```
%%%% Output: display_data
%% Cell type:code id: tags:
``` haskell
[0.1,0.3..0.9]
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
- infinite lists possible (but don't do it like this! this will take a while... )
%% Cell type:code id: tags:
``` haskell
[1..]
```
%% Cell type:markdown id: tags:
- should normally be named and then used
%% Cell type:code id: tags:
``` haskell
a = [1,3..]
take 5 a
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
## Indexing and manipulating of lists
get first list element
%% Cell type:code id: tags:
``` haskell
head a
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
get last list element
%% Cell type:code id: tags:
``` haskell
b = [1,3,6,8]
last b
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
get list without first element (head)
%% Cell type:code id: tags:
``` haskell
tail b
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
get list without last element
%% Cell type:code id: tags:
``` haskell
init b
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
first `x` elements
%% Cell type:code id: tags:
``` haskell
take 2 a
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
drop first `x` elements
%% Cell type:code id: tags:
``` haskell
drop 2 b
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
element at position a (note: haskell starts index at 0)
%% Cell type:code id: tags:
``` haskell
b
b !! 2
```
%%%% Output: display_data
%%%% Output: display_data
%% Cell type:markdown id: tags:
length of a list
%% Cell type:code id: tags:
``` haskell
length b
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
Check if list is empty
%% Cell type:code id: tags:
``` haskell
null b
```
%%%% Output: display_data
%% Cell type:code id: tags:
``` haskell
null []
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
reverse a list
%% Cell type:code id: tags:
``` haskell
reverse b
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
minimal element of a list (req.: elements are sortable) ($\min (a_1,...,a_n)$)
%% Cell type:code id: tags:
``` haskell
minimum b
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
maximal element of a list (req.: elements are sortable) ($\max (a_1,...,a_n)$)
%% Cell type:code id: tags:
``` haskell
maximum b
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
sum of all elements in a list ($\sum_i a_i$)
%% Cell type:code id: tags:
``` haskell
sum b
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
product of all elements in a list ($\prod_i a_i$)
%% Cell type:code id: tags:
``` haskell
product b
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
check if given element is in list ($x \in a$)
%% Cell type:code id: tags:
``` haskell
elem 3 b
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
## concat lists
- adding lists
%% Cell type:code id: tags:
``` haskell
[1,2,3] ++ [4,5,6]
```
%%%% Output: display_data
%% Cell type:code id: tags:
``` haskell
"hello" ++ " " ++ "world"
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
- insert elements at the beginning (operator ``:``)
%% Cell type:code id: tags:
``` haskell
2:[3,4]
[2] ++ [3,4]
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
these two are identical
%% Cell type:code id: tags:
``` haskell
[1,2,3] == 1:2:3:[]
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
## create lists (list comprehensions)
inspired by mathematical notation we can generate lists
[expr | condition, ,...]
while *condition* is one of
1. generator `var <- list`
2. boolean expression
3. binding
%% Cell type:code id: tags:
``` haskell
[(i,j) | i <- [1,2], j <- [1..3]]
```
%%%% Output: display_data
%% Cell type:code id: tags:
``` haskell
removeNonUppercase :: [Char] -> [Char]
removeNonUppercase st=[c | c <- st, c `elem` ['A'..'Z']]
```
%% Cell type:code id: tags:
``` haskell
removeNonUppercase "HallO"
```
%%%% Output: display_data
%% Cell type:code id: tags:
``` haskell
[x | x <- [50..60], odd x]
```
%%%% Output: display_data
%% Cell type:code id: tags:
``` haskell
oddFifty list=[odd x | x <- list]
oddFifty [50..100]
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
## Sets
with haskell creating mathematical sets is rather easy (but: better is `Data.Set` which we will cover later)
$S=\{x^2 | x \in [1..5] , x^2 < 20\}$
%% Cell type:code id: tags:
``` haskell
[x^2 | x <-[1..5], x^2<20 ]
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
*infinite sets* are possible also (but bind them or make a function definition)
Let
$S=\{\ln(x) | x \in \mathbb{N}_+\}$
create generator for $\mathbb{N}$ (finite in practice):
%% Cell type:code id: tags:
``` haskell
let s = [log x | x <-[1..] ]
```
%% Cell type:code id: tags:
``` haskell
take 3 s
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
## functions for infinite lists
infinite cycle a list with `cycle`
cycle a
%% Cell type:code id: tags:
``` haskell
take 10 (cycle [1,2,3])
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
infinite repeat element a
repeat a
%% Cell type:code id: tags:
``` haskell
take 3 (repeat "LOL ")
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
replicate given element a x times
replicate x a
%% Cell type:code id: tags:
``` haskell
replicate 3 10
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
## Tuples
a tuple $(a,b,...)$ consists of several elements of different type (0 or $n \ge 2$)
the tuple without content `()` is called *unary*
the tuple without content `()` is called *nullary*
%% Cell type:code id: tags:
``` haskell
let t = (1,'a')
:type t
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
tuples are normally used for simple data organisation
- first element of a tuple
%% Cell type:code id: tags:
``` haskell
fst t
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
- second element of a tuple
%% Cell type:code id: tags:
``` haskell
snd t
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
two lists can be combined to a single list of two-tuples:
%% Cell type:code id: tags:
``` haskell
let a = [1..4]
let b = ['a'..'d']
zip a b
```
%%%% Output: display_data
......
%% Cell type:markdown id: tags:
# Higher order functions
## Currying
Transform a function in multiple variables into a chain of single-argument functions:
*Example*:
$f: X \times Y \times Z \rightarrow N$
becomes
$\text{curry}(f): X \rightarrow (Y \rightarrow (Z \rightarrow N))$
---
Haskell functions are *curried by default*, i.e.
- they only have a single argument ...
- ... but may return another function.
*Example*: `max` function
```haskell
max :: (Ord a) => a -> a -> a
```
which should be read as (*right associative*)
```haskell
max :: (Ord a) => a -> (a -> a)
```
It is possible, albeit rarely useful, to `uncurry` a function:
```haskell
uncurry max :: (Ord a) => (a, a) -> a
```
%% Cell type:code id: tags:
``` haskell
max 1 2
```
%%%% Output: display_data
%% Cell type:code id: tags:
``` haskell
uncurry max (1, 2)
```
%%%% Output: display_data
%% Cell type:markdown id: tags:
## Partial application
... is related to currying: fix one or more arguments of a multi-argument function to obtain a function of the *remaining* arguments:
*Example*:
$f: X \times Y \times Z \rightarrow N$
becomes
$\text{partial}(f)(x): Y \times Z \rightarrow N$
for fixed $x \in X$
---
*Example*: `max 1`
%% Cell type:code id: tags:
``` haskell
(max 1) 2
```
%%%% Output: display_data