v3 alp1 tupel list 2013 - inf.fu-berlin.de · absc ( real, img ) = sqrt( real*real + img*img )...
TRANSCRIPT
ALP IFunktionale Programmierung
Zusammengesetzte Datentypen in Haskell
Prof. Dr. Margarita Esponda
WS 2012/2013
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Zusammengesetzte Datentypen
Tupel
List
String
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Zusammengesetzte Datentypen
Ein Tupel ist eine Ansammlung von zwei oder mehreren
Daten, die unterschiedliche Datentypen besitzen können.
Tupel-Datentyp
Beispiele:
( "Peter" , "Meyer", 439990 ) :: ( String, String, Int )
Mit Hilfe von Tupeln können zusammengehörige Daten als
Einheit behandelt werden.
( 2.5, 3.0 ) :: ( Double, Double )
Studierende
Punkt
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Tupel-Typ
Funktionsdefinition mit Tupeln:
distance :: (Double, Double) -> (Double, Double) -> Double
distance (x1,y1) (x2,y2) = sqrt (squareX + squareY )
where
squareX = (x1-x2) * (x1-x2)
squareY = (y1-y2) * (y1-y2)
Prof. Dr. Margarita Esponda
Funktionale Programmierung
rgbColor :: (Int, Int, Int) → [Char]
rgbColor (red, green, blue) = case (red, green, blue) of
(0,0,0) → "black"
(255,255,255) → "white"
(255,0,0) → "red"
(0,255,0) → "green"
(0,0,255) → "blue"
otherwise → "other color"
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Tupel-Datentyp
Tupel-TypEin Tupel-Typ hat folgende allgemeine Form:
( t1 , t2 , … , tn ), wobei t1 , t2 , … , tn beliebige
Datentypen sind
Zwei einfache Funktionen für Tupel sind:
fst (x, y) = x
snd (x, y) = y
Die erwartete Tupel-Struktur wird in den Argumenten sichtbar
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Tupel-Typ
Funktionsdefinition mit Tupeln:
distance :: (Double, Double) -> (Double, Double) -> Double
distance p1 p2 = sqrt(xd^2 + yd^2)
where
xd = (fst p1) - (fst p2)
yd = (snd p1) - (snd p2)
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Pattern-Matching
oder0 :: Bool -> Bool -> Bool
oder0 False False = False
oder0 False True = True
oder0 True False = True
oder0 True True = True
oder :: Bool -> Bool -> Bool
oder False False = False
oder x y = True
und :: Bool -> Bool -> Bool
und True True = True
und _ _ = False
beliebige Argumente vom Typ Bool
myNot :: Bool -> Bool
myNot True = False
myNot False = True
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Pattern-Matching
In Haskell ist es möglich durch Pattern-Matching eine Auswahl
verschiedener Funktionsgleichungen zu definieren.
Allgemeine Form:
f p11 p12 … p1n = e1
f p21 p22 … p2n = e2
…..f pk1 pk2 … pkn = ek
Die pij Muster werden von oben nach unten und von links nach
rechts geprüft.
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Typ-SynonymeTyp-Synonyme werden verwendet, um die Lesbarkeit von
Programmen mit Hilfe von aussagekräftigen Typ-Namen zu
verbessern.
Allgemeine Form:
type Typname = …….
Beispiele:type Student = (String, String, Int)
type Point = (Double, Double)
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Typ-Synonyme
Funktionsdefinition mit Typ-Synomyme:
type Point = (Double, Double)
distance :: Point -> Point -> Double
distance (x1,y1) (x2,y2) = sqrt (sumSq (x1-x2) (y1-y2))
where
sumSq x y = x*x + y*y
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Typ-Synonyme
Text
type Complex = (Double, Double)
realPart :: Complex -> DoublerealPart ( real, img ) = real
imgPart :: Complex -> DoubleimgPart ( real, img ) = img
sumC :: Complex -> Complex -> ComplexsumC (r1,i1) (r2,i2) = (r1+r2, i1+i2)
absC :: Complex -> DoubleabsC ( real, img ) = sqrt( real*real + img*img )
Prof. Dr. Margarita Esponda
Funktionale Programmierung
13
Rekursion ist ein fundamentales Konzept in der Mathematik
Rekursion ist ein fundamentales Konzept in der Informatik
- eine Denkform für Problembeschreibung
- eine Methode zur Problemlösung
- enge Beziehung zur mathematischen Induktion
Rekursion
Rekursive Funktionsdefinitionen sind die wichtigste
Programmiertechnik in funktionalen Programmiersprachen.
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Rekursive Funktionen
factorial :: Int -> Int
factorial n = if n==0
then 1
else n * factorial (n-1)
Typisches Beispiel: Die Fakultätsfunktion
Wie viele Permutationen kann eine Reihe von Objekten maximal haben?
Prof. Dr. Margarita Esponda
Funktionale Programmierung
factorial :: Int -> Int
factorial n | n==0 = 1
| otherwise = n*factorial (n-1)
factorial :: Integer -> Integer
factorial n | n==0 = 1
| True = n*factorial (n-1)
richtig aber nicht schön
Rekursive Funktionen
factorial :: Int -> Int
factorial 0 = 1
factorial n = n * factorial (n-1)
bigFactorial :: Integer -> Integer
bigFactorial 0 = 1
bigFactorial n = n * bigFactorial (n-1)
Die Fakultätsfunktion
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Pattern-Matching
Rekursive Funktionen
factorial :: Int -> Int
factorial n = n * factorial (n-1)
factorial 0 = 1
Die Fakultätsfunktion
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Pattern-Matching
Warning: Pattern match(es) are overlapped In the definition of `factorial': factorial 0 = ...Ok, modules loaded:
factorial 0 *** Exception: stack overflow
Rekursive Funktionen
ggt :: Integer → Integer → Integer
ggt p q | p>q = ggt (p-q) q
| p==q = p
| p<q = ggt p (q-p)
noch ein Klassiker:
Größter gemeinsamer Teiler von zwei natürlichen Zahlen a, b
Euklid (originaler Algorithmus)
Probleme?
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Rekursive Funktionen
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Probleme?
ggt 20 8 ⇒ (20-8) 8
⇒ ggt 12 8
⇒ ggt (12-8) 8
⇒ ggt 8 4
⇒ ggt 4 4
⇒ 4
ggt 8 0 ⇒ ggt (8-0) 0 ⇒ ggt 8 0 ⇒ ggt 8 0
.... :(
ggt :: Integer → Integer → Integer
ggt p q | p>q = ggt (p-q) q | p==q = p | p<q = ggt p (q-p)
Rekursive Funktionen
1. Lösung:ggt a b
| b == 0 = a
| otherwise = ggt b (a `mod` b)
Prof. Dr. Margarita Esponda
Funktionale Programmierung
2. Lösung:ggt a b
| a == 0 && b == 0 = ???
| b == 0 = a
| otherwise = ggt b (a `mod` b)
Pizzaproblem (Jakob Steiner, 1826)
Wie viele Pizza-Teile entstehen maximal, wenn eine Pizza mit n geraden Schnitten aufgeteilt wird?
maxSurfaces :: Int -> IntmaxSurfaces 0 = 1maxSurfaces n = maxSurfaces (n - 1) + n
Prof. Dr. Margarita Esponda
Funktionale Programmierung
ab=a + ba
Rekursive Funktionen
Zwei positive reelle Zahlen stehen im Verhältnis der goldenen Zahl, wennBerechnung des goldenen Schnitts
gilt, mit a > b > 0.
goldenRatio :: Int -> DoublegoldenRatio n | n == 0 = 1 | n > 0 = 1 + 1 / goldenRatio (n-1) | otherwise = error "not defined for negative numbers"
Φ = 1+ 1Φ
Goldener Schnitt =
Prof. Dr. Margarita Esponda
Funktionale Programmierung
22
Fibonacci-ZahlenProblem:
Zu Beginn eines Jahres gibt es genau ein Paar neugeborener Kaninchen.
Ein Paar neugeborener Kaninchen ist erst nach einem Monat fortpflanzungsfähig, sodass erst nach zwei Monaten ein neues Kaninchenpaar zur Welt gebracht werden kann.
Jedes nicht neugeborene Kaninchen bekommt ein neues Kaninchenpaar monatlich.
Wie viele Kaninchen gibt es nach einem Jahr, wenn keines der Kaninchen stirbt?
Prof. Dr. Margarita Esponda
Funktionale Programmierung
24
Fibonacci-ZahlenDer Stammbaum einer Drohne
8
13
Drohne
1Mutter
2Großeltern
3Urgroßeltern
5Ururgroßeltern
Prof. Dr. Margarita Esponda
Funktionale Programmierung
27
Fibonacci-Zahlen
0 1
fib(0) fib(1)
1
fib(2)
+
Prof. Dr. Margarita Esponda
Funktionale Programmierung
28
Fibonacci-Zahlen
0 1
fib(0) fib(1)
1
fib(2) fib(3)
+ 2
Prof. Dr. Margarita Esponda
Funktionale Programmierung
29
Fibonacci-Zahlen
0 1
fib(0) fib(1)
1
fib(2) fib(3)
+ 2 3
fib(4)
Prof. Dr. Margarita Esponda
Funktionale Programmierung
30
Fibonacci-Zahlen
0 1
fib(0) fib(1)
1
fib(2) fib(3)
2 3
fib(4) fib(5)
+ 5
Prof. Dr. Margarita Esponda
Funktionale Programmierung
31
Fibonacci-Zahlen
0 1
fib(0) fib(1)
1
fib(2)
+2
fib(3)
3
fib(4)
5
fib(5)
8
fib(6)
13
fib(7)
. . . . .
fib(n)fib(n-2) fib(n-1). . . . . +
fib ( 0 ) = 0
fib ( 1 ) = 1
fib ( n ) = fib ( n-2 ) + fib ( n-1 ) für alle n>1
Formale rekursive Definition:
+
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Berechnung der Fibonacci-Zahlen1. Lösung
fib 5
fib 3 fib 4
fib 1 fib 2 fib 2 fib 3
fib 0 fib 1
fib 7
fib 6
fib 4 fib 5
fib 2 fib 3 fib 3 fib 4
fib 0 fib 1 fib 1 fib 2 fib 0 fib 1 fib 1 fib 2 fib 1 fib 2 fib 2 fib 3
fib 0 fib 1 fib 0 fib 1 fib 1 fib 2fib 0 fib 1
fib 0 fib 1wiederholte Berechnungen der fib-Funktion
Beispiel: fib 7
fib 0 = 0fib 1 = 1fib n = fib (n-1) + fib (n-2)
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Berechnung der Fibonacci-Zahlen
fib 5
fib 3 fib 4
fib 1 fib 2 fib 2 fib 3
fib 0 fib 1
fib 7
fib 6
fib 4 fib 5
fib 2 fib 3 fib 3 fib 4
fib 0 fib 1 fib 1 fib 2 fib 0 fib 1 fib 1 fib 2 fib 1 fib 2 fib 2 fib 3
fib 0 fib 1 fib 0 fib 1 fib 1 fib 2fib 0 fib 1
fib 0 fib 1
Beispiel: fib 7
Fallgrube
Wenn wir fib 40 mit unserer rekursiven Implementierung berechnen,
wird:
fib 39 einmal berechnetfib 38 2 mal berechnetfib 37 3 mal berechnetfib 36 5 mal berechnetfib 35 8 mal berechnet. . .fib 0 165 580 141 mal berechnet
Beim Aufruf von fib 40 werden 331 160 281 Funktionsaufrufe gemacht
Berechnung der Fibonacci-ZahlenWie viele Reduktionsschritte brauchen wir, um fib n zu berechnen?
fib 0
1
fib 1
1
fib 2 fib 3 fib 4 fib 5
8
fib 6
13
Die Anzahl der Reduktionen für fib n ist gleich fib (n+1)
Die Anzahl der rekursive Aufrufe ist eine
exponentielle Funktion von n.
+ =2 3+ =1
5+ =2 3
8+ =3 5
13+ =3 5
532 Reduktionen
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Berechnung der Fibonacci-Zahlen
2. Lösung
fib' n = quickFib 0 1 n
where
quickFib a b 0 = a
quickFib a b n = quickFib b (a+b) (n-1)
quickFib funktioniert nur, wenn diese mit den ersten zwei Fibonacci-Zahlen gestartet wird.
Zähler
Innerhalb jedes rekursiven Aufrufs wird eine neue Fibonacci-Zahl berechnet und der Zähler verkleinert. Die neue Zahl und ihr Vorgänger werden beim nächsten rekursiven Aufruf als Parameter weitergegeben.
Für die Berechnung von quickFib n benötigen wir n Reduktionen,
Anzahl der Reduktionen
Prof. Dr. Margarita Esponda
Funktionale Programmierung
36
Fibonacci-Zahlen
nextFib :: (Integer, Integer) -> (Integer, Integer)nextFib (a,b) = (b, a+b)
fib n = fst ( fibTuple n )
fibTuple n | n==0 = (0, 1) | otherwise = nextFib (fibTuple (n-1))
Text
3. Lösung mit Tupeln:
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Listen
Symbol Name Bedeutung
[ ] nil leere Liste
(:) cons am Anfang anfügen
Listen sind die wichtigsten Datenstrukturen in funktionalen
Programmiersprachen
Listen stellen Sammlungen von Objekten dar, die den gleichen
Datentyp besitzen
Listen sind dynamische Datenstrukturen, die mit Hilfe folgender
Daten-Konstruktoren erzeugt werden können
Prof. Dr. Margarita Esponda
Funktionale Programmierung
ListenListen sind rekursive Strukturen:
Eine Liste ist entweder leer
[]
oder ein konstruierter Wert, der aus einem Listenkopf x und einer Restliste xs besteht.
x : xs
Der Typ einer Liste, die Elemente des Typs t enthält, wird
mit [t] bezeichnet.
head tail
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Ausdrücke mit ListenBeispiele:
[1, 2, 3] :: [Integer]
1: [0,3,7] :: [Integer]
[ [0.3, 0.0], [] ] :: [[Double]]
'a' : "Hello" :: [Char]
[( 3, 0 ), ( 2, 1)] :: [ (Integer, Integer) ]
[ True, True, False ] :: [ Bool ]
[ e1, e2, e3, … ,en ]
Syntaktische Abkürzung:
Datentyp
Allgemeine Syntax:
Ausdruck
e1:[e2:[e3: … :en:[]]] e1:e2: … :en:[]
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Ausdrücke mit ListenBeispiele:
"hello"
[1, 2, 3] 1:[2, 3] 1 : 2 : 3 : []
[( 3, 0 ), ( 2, 1)]
'h' : "ello"
['h', 'e', 'l', 'l', 'o']
( 3, 0 ) : [( 2, 1)]
[[3, 0 ], [2, 1]] [3, 0] : [2, 1] : []
equiv.
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Funktionen mit Listen
kopf :: [ Integer ] -> Integer
kopf (x:xs) = x
kopf [] = error "ERROR: empty list"
rumpf :: [ Integer ] -> [ Integer ]
rumpf (x:xs) = xs
rumpf [] = error "ERROR: empty list"
Prof. Dr. Margarita Esponda
Funktionale Programmierung
summe :: [Integer] -> Integer
summe ls = if ls == []
then 0
else ( kopf ls ) + summe (rumpf ls)
Addiert alle Zahlen innerhalb einer Liste
Lösung mit Pattern-Matching über der Listenstruktur
summe :: [Integer] -> Integer
summe [] = 0
summe (x : xs) = x + summe xs
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Funktionen mit Listen
Funktionsdefinitionen mit Listen
multList :: [Integer] -> Integer
multList [] = error "the function is not defined for []"
multList [x] = x
multList (x:xs) = x * multList xs
laenge :: [Int] -> Int
laenge [] = 0
laenge (x:xs) = 1 + laenge xs
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Zehnersystem → Binärsystem
42 0
121
42 10
10
5
0
2
1
011
0
= 1010102mod 2div 2
dec2bin :: Int -> [Int]
dec2bin n | n<2 = [n]
| otherwise = dec2bin (n`div`2) ++ [n `mod`2]
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Funktionen mit Listen
drehe [1,2,3] ⇒ drehe [2,3] ++ [1]
⇒ drehe [3] ++ [2] ++ [1]
⇒ drehe [] ++ [3] ++ [2] ++ [1]
⇒ [] ++ [3] ++ [2] ++ [1]
drehe [] = []
drehe (x:xs) = drehe xs ++ [x]
Verkettungsoperator
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Funktionen mit Listen
binary2decimal xs = bin2dec ( drehe xs)
bin2dec :: [Int] -> Int
bin2dec [] = 0
bin2dec (x:xs) = x + 2*(bin2dec xs)
1011012 =
= 2(2(2(2(2(1)+0)+1)+1)+0)+1
1*25 + 0*24 + 1*23 + 1*22 + 0*21 + 1*20
Prof. Dr. Margarita Esponda
Funktionale Programmierung
Funktionen mit Listen
bitXOr :: [Int] -> [Int] -> [Int]
bitXOr [] [] = []
bitXOr (x:xs) (y:ys) = (exoder x y): (bitXOr xs ys)
bitXOr _ _ = error "the two lists are not of the same length"
exoder :: Int -> Int -> Int
exoder x y | x==y = 0
| otherwise = 1
Prof. Dr. Margarita Esponda
Funktionale Programmierung