Funktionen Höherer Ordnung

Werbung
ALP I
Funktionen Höherer Ordnung
WS 2009/2010
Prof. Dr. Margarita Esponda
Prof. Dr. Margarita Esponda
1
Funktionen Höherer Ordnung
Eine Funktion wird als Funktion höherer Ordnung
bezeichnet, wenn Funktionen als Argumente verwendet
werden oder wenn eine Funktion als Ergebnis zurück
gegeben wird.
Beispiel:
twice :: ( a -> a ) -> a -> a
twice f x = f ( f x ) )
Anwendung:
twice quadrat 3 => quadrat (quadrat 3) => 81
Prof. Dr. Margarita Esponda
2
Sektionen
Jede arithmetische Infix-Operation kann in eine Curried-Funktion
verwandelt werden, indem der Operator in runden Klammern und
als Präfix-Funktion geschrieben wird.
Beispiel:
(+) 3 4
dann sieht eine partielle Auswertung der Funktion wie folgt aus:
(+ 3) 4
Funktion, die zu einem beliebigen
Argument die Zahl 3 addiert
Im allgemeinen, wenn ⊕ ein Infix-Operator ist, werden Ausdrücke
mit der Form (⊕ x) oder (x ⊕) Sektionen genannt.
Prof. Dr. Margarita Esponda
3
Funktionen Höherer Ordnung
Typische Beispielfunktion:
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = f x : map f xs
map f
[2, 3, 6, 0]
=> [f(2), f(3), f(6), f(0)]
Die Funktion f wird auf jedes Element der Liste angewendet
map (^2) [2, 3, 6, 0]
Prof. Dr. Margarita Esponda
=> [4, 9, 36, 0]
4
Funktionen Höherer Ordnung
Eine andere Definition der map-Funktion mit
Listen-Generatoren ist:
map :: (a -> b) -> [a] -> [b]
map f xs = [ f x | x<-xs ]
Anwendung:
map length [ "Eins" , "Zwei" , "Drei" , "Vier" ] => [4, 4, 4, 4]
Prof. Dr. Margarita Esponda
5
Funktionen Höherer Ordnung
Die filter-Funktion
Die filter-Funktion soll aus einer Liste nur die
Elemente auswählen, die eine bestimmte
Bedingung erfüllen.
Beispiel:
filter (<3) [2,5,0,1,7]
Prof. Dr. Margarita Esponda
=>
[2,0,1]
6
Funktionen Höherer Ordnung
Die filter-Funktion
1. Definition:
filter :: (a -> Bool) -> [a] -> [a]
filter p [] = []
filter p (x:xs)
| p x = x : filter p xs
Bedingung
| otherwise = filter p xs
2. Definition:
filter :: (a -> Bool) -> [a] -> [a]
filter p xs = [ x | x <- xs, p x ]
Prof. Dr. Margarita Esponda
7
Funktionen Höherer Ordnung
Die filter-Funktion
Beispiel:
Wir können den Quicksort-Algorithmus mit Hilfe der
filter-Funktion wie folgt definieren:
qsort [] = []
qsort [x] = [x]
qsort (x:xs) = qsort( filter (<=x) xs ) ++ [x] ++ qsort( filter (>x) xs )
Prof. Dr. Margarita Esponda
8
Funktionen Höherer Ordnung
Nehmen wir an, wir möchten alle Zahlen innerhalb einer
Liste miteinander addieren
addAll:: (Num a) => [a] -> a
addAll [] = 0
addAll (x:xs) = x + addAll xs
oder die Und-Operation über alle Elemente einer Liste
berechnen
trueAll:: [Bool] -> Bool
trueAll [] = True
trueAll (x:xs) = x && (trueAll xs)
Prof. Dr. Margarita Esponda
9
Funktionen Höherer Ordnung
Gemeinsamkeiten von beiden Funktionen sind:
- Binär-Operator
- Konstanter Wert, wenn die Liste leer ist.
- gleiches Rekursions-Muster
Wir können eine verallgemeinerte Funktion definieren,
die beide Probleme löst
Beispiel:
trueAll = betweenAll (&&) True
addAll
= betweenAll (+) 0
multAll = betweenAll (*) 1
Prof. Dr. Margarita Esponda
10
Funktionen Höherer Ordnung
Verallgemeinerungen sind immer gut!
betweenAll :: (a -> a -> a) -> a -> [a] -> a
Binäre Operation
Wert der Funktion,
wenn die Liste leer ist
betweenAll f
k [] = k
betweenAll f
k (x:xs) = f x (betweenAll f k xs)
Prof. Dr. Margarita Esponda
11
Funktionen Höherer Ordnung
foldr-Funktion
In Haskell ist bereits eine allgemeine Funktion
vordefiniert, die Faltungs-Operator genannt wird
Definition:
foldr f z []
=z
foldr f z (x:xs) = f x (foldr f z xs)
foldr (*) 1 [1,2,3,4]
*
:
1
1
:
2
:
3
2
*
3
:
4
Prof. Dr. Margarita Esponda
=>
*
[]
=>
24
*
4
1
12
Funktionen Höherer Ordnung
Folgende Standard-Funktionen von Haskell können
mit Hilfe des Faltungs-Operators definiert werden:
Beispiele:
Prof. Dr. Margarita Esponda
sum
= foldr (+) 0
product
= foldr (*) 1
or
= foldr (||) False
and
= foldr (&&) True
13
Funktionen Höherer Ordnung
foldl-Funktion
Definition:
foldl f z []
=z
foldl f z (x:xs) = foldl f (f z x) xs
foldl f k [8,6,4,2]
f
:
8
f
:
6
4
f
[]
k
6
4
f
:
2
Prof. Dr. Margarita Esponda
=>
:
8
2
14
Faltungs-Operatoren
Beispiele:
foldr (*) 1 [1..5]
=>
120
Fakultät-Funktion
factorial n = foldr (*) 1 [1..n]
Potenz-Funktion für positive ganzzahlige Potenzen
pow b e
= foldl (*) 1 (take e [b,b..b])
foldr max 0 [-6,3,6,12,14,0,23]?
Prof. Dr. Margarita Esponda
15
Funktionen Höherer Ordnung
zipWith-Funktion
zip (x:xs) (y:ys)
zip xs
ys
= (x,y) : zip xs ys
= []
Die zip-Funktion kombiniert die Elemente aus zwei Listen und
liefert eine Liste von Tupeln zurück.
Die zipWith-Funktion bekommt zwei Listen und eine Funktion
als Parameter und berechnet eine neue Liste, indem jeweils
die Elemente der beiden Listen mit der angegebenen Funktion
verknüpft werden.
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith f (x:xs) (y:ys) = (f x y):(zipWith f xs ys )
zipWith f _ _ = []
Prof. Dr. Margarita Esponda
16
Funktionen Höherer Ordnung
Anwendungsbeispiel der zipWith-Funktion:
Skalar-Produkt von zwei Vektoren
v1 . v2
v1 = (x1, x2, .. , xn)
v2 = (y1, y2, .. , yn)
ist
v1 . v2 = x1. y1 + x2 . y2 + .. + xn. yn
skalarProd ::[Int] -> [Int] -> Int
skalarProd x y
Prof. Dr. Margarita Esponda
= foldl (+) 0 (zipWith (*) x y)
17
Funktionen Höherer Ordnung
Funktionskomposition
g
f
A
B
f
C
°g
(.) :: (b → c) → (a → b) → (a → c)
Beispiel:
ungerade = not . gerade
Prof. Dr. Margarita Esponda
18
Funktionen Höherer Ordnung
all-Funktion
Entscheidet, ob alle Elemente einer Liste eine
gegebene Bedingung erfüllen.
all :: (a → Bool) → [a] → Bool
all p xs = and [p x | x ← xs]
Beispiel:
all even [2 ,4 ,6 ,8]
all (==3)
Prof. Dr. Margarita Esponda
=> True
[3,4,3,0,3] => False
19
Funktionen Höherer Ordnung
any-Funktion
Entscheidet, ob mindestens ein Element einer Liste
eine gegebene Bedingung erfüllt.
any :: (a → Bool) → [a] → Bool
any p xs = or [p x | x ← xs]
Beispiel:
any even [2 ,3 ,6 ,8]
=> True
any (==3) [3,4 ,3 ,0 ,3] => True
Prof. Dr. Margarita Esponda
20
Funktionen Höherer Ordnung
Wir können eine allgemeinere Quicksort-Algorithmus definieren,
indem die Vergleichsoperation angegeben wird.
qsort v [] = []
qsort v [x] = [x]
qsort v (x:xs) = qsort v [s|s<-xs, v s x]++[x]++qsort v [b|b<-xs, not (v b x)]
Anwendungsbeispiel:
qsort (<) [3,2,1, 5,4]
Prof. Dr. Margarita Esponda
oder
qsort (>=) [3,2,1, 5,4]
21
Funktionen Höherer Ordnung
takeWhile-Funktion
So lange eine Bedingung erfüllt wird, werden Elemente aus
eine Liste genommen.
takeWhile :: (a → Bool) → [a] → [a]
takeWhile p [] = []
takeWhile p (x:xs)
| p x = x : takeWhile p xs
| otherwise = []
Beispiel:
takeWhile (<9)
Prof. Dr. Margarita Esponda
[2, 5, 7, 9, 11]
=>
[2, 5, 7]
22
Funktionen Höhere Ordnung
dropWhile-Funktion
So lange eine Bedingung erfüllt wird, werden Elemente aus
einer Liste gelöscht.
dropWhile :: (a → Bool) → [a] → [a]
dropWhile p [] = []
dropWhile p (x:xs)
| p x = dropWhile p xs
| otherwise = x:xs
Beispiel:
dropWhile
Prof. Dr. Margarita Esponda
isSpace
"
Hello"
=>
"Hello"
23
Berechnung der Fibonacci-Zahlen
rekursiv:
fib 0 = 0
fib 1 = 1
fib n = fib (n-2) + fib (n-1)
Die rekursive Berechnung der Fibonacci-Zahlen hat
eine exponentielle Komplexität
O((1,618...)n)
Prof. Dr. Margarita Esponda
24
Berechnung der Fibonacci-Zahlen
Rekursiv
f(7)
f(5)
f(3)
f(1)
f(2)
f(6)
f(4)
f(2)
f(3)
f(4)
f(2)
f(5)
f(3)
f(3)
f(4)
f(0)f(1) f(0)f(1) f(1)f(2)f(0)f(1)f(1)f(2)f(1)f(2) f(2)f(3)
f(0)f(1)
f(0)f(1) f(0)f(1)f(1)f(2)
f(0)f(1)
Prof. Dr. Margarita Esponda
25
Berechnung der Fibonacci-Zahlen
Rekursiv
f(7)
f(5)
f(3)
f(1)
f(2)
f(6)
f(4)
f(2)
f(3)
f(4)
f(2)
f(5)
f(3)
f(3)
f(4)
f(0)f(1) f(0)f(1) f(1)f(2)f(0)f(1)f(1)f(2)f(1)f(2) f(2)f(3)
f(0)f(1)
f(0)f(1)f(0)f(1) f(1)f(2)
f(0)f(1)
wiederholte Berechnungen
Prof. Dr. Margarita Esponda
26
Berechnung der Fibonacci-Zahlen
Rekursiv
f(7)
f(5)
f(3)
f(1)
f(2)
f(6)
f(4)
f(2)
f(3)
f(4)
f(2)
f(5)
f(3)
f(3)
f(4)
f(0)f(1) f(0)f(1) f(1)f(2)f(0)f(1)f(1)f(2)f(1)f(2) f(2)f(3)
f(0)f(1)
Fallgrube
Wenn wir fib(40) mit unserer
rekursiven Implementierung
berechnen,
wird:
f(0)f(1) f(0)f(1) f(1)f(2)
fib(39) einmal berechnet
f(0)f(1)
fib(38) 2 mal berechnet
fib(37) 3 mal berechnet
fib(36) 5 mal berechnet
fib(35) 8 mal berechnet
. . . . mal berechnet
fib(0) 165 580 141 mal berechnet
Beim Aufruf von fib(40) werden 331 160 281 Funktionsaufrufe gemacht
Prof. Dr. Margarita Esponda
27
Funktionen Höherer Ordnung
Folgende Funktion berechnet die Fibonacci-Zahlen in
linearer Zeit
O(n)
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
fibs
0:1:1:2:3:5:8:...
tail fibs
0:1:1:2:3:5:...
zipWith (+) 1 : 2 : 3 : 5 : 8 : . . .
Anwendungsbeispiel:
take 40 fibs
Prof. Dr. Margarita Esponda
28
Herunterladen