ALP I Einführung in Haskell Teil II

Werbung
26.10.2009
ALP I
Einführung in Haskell
Teil II
WS 2009/2010
Prof. Dr. Margarita Esponda
1
26.10.2009
Zusammengesetzte Datentypen
Tupel
List
String
2
26.10.2009
Zusammengesetzte Datentypen
Tupel-Datentyp
Ein Tupel ist eine Ansammlung von zwei oder mehreren
Daten, die unterschiedliche Datentypen besitzen können.
Mit Hilfe von Tupel können zusammengehörige Daten als
Einheit behandelt werden.
Studierende
Beispiele:
( "Peter" , "Meyer", 439990 )
( 2.5, 3.0 )
:: ( String, String, Int )
:: ( Double, Double )
Punkt
3
26.10.2009
Tupel-Typ
Ein Tupel-Typ hat folgende allgemeine Form:
( t1 , t2 , … , tn )
mit t1 , t2 , … , tn beliebige Datentypen
Funktionsdefinition mit Tupeln:
distance (x1,y1) (x2,y2) = sqrt (sumSquares (x1-x2) (y1-y2) )
sumSquares :: Double -> Double -> Double
sumSquares x y = squareX + squareY
where
squareX = x * x
squareY = y * y
4
26.10.2009
Typ-Synonyme
Typsynonyme werden verwendet, um die Lesbarkeit von
Programmen mit Hilfe von aussagekräftigen Typ-Namen zu
verbessern.
Allgemeine Form:
type Typname = …….
Beispiel:
type Student = (String, String, Int)
5
26.10.2009
Typ-Synonyme
Beispiel:
type Complex = (Double, Double)
realPart :: Complex -> Double
realPart ( real, img ) = real
imgPart :: Complex -> Double
imgPart ( real, img ) = img
sumC :: Complex -> Complex -> Complex
sumC (r1,i1) (r2,i2) = (r1+r2, i1+i2)
absC :: Complex -> Double
absC ( real, img ) = sqrt( real*real + img*img )
6
26.10.2009
Listen
• 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
Symbol
Name
Bedeutung
[]
nil
leere Liste
(:)
cons
am Anfang anfügen
7
26.10.2009
Listen
Listen sind rekursive Strukturen:
Eine Liste ist entweder leer
[]
oder ein konstruierter Wert, der aus einem Listenkopf x und
einer Restliste xs besteht.
head
tail
x:xs
Der Typ einer Liste, die Elemente des Typs t enthält, wird mit
[t] bezeichnet.
8
26.10.2009
Listen
Beispiele:
Datentyp der Liste
[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 ]
Allgemeine Syntax:
[ e1, e2, e3, … ,en ]
Syntaktische Abkürzung:
e1:[e2:[e3: … :en:[]]]
e1:e2: … :en:[]
9
26.10.2009
Listen
summe :: [ Integer ] -> Integer
summe
ls
=
if
ls == []
then
0
else ( kopf ls ) + summe (rumpf ls )
kopf :: [ Integer ] -> Integer
kopf (x:xs) = x
kopf [] = error "ERROR: empty list"
rumpf :: [ Integer ] -> [ Integer ]
rumpf (x:xs) = xs
rumpf [] = error "ERROR: empty list“
10
26.10.2009
Funktionsdefinitionen mit Listen
sumList :: [Integer] -> Integer
sumList [] = 0
sumList (x:xs) = x + sumList xs
multList :: [Integer] -> Integer
multList [x] = x
multList (x:xs) = x * multList xs
multList [] = error "the function is not defined for []"
laenge :: [Int] -> Int
laenge [] = 0
laenge (x:xs) = 1 + laenge xs
11
26.10.2009
Pattern-Matching
In Haskell es ist möglich, die erwartete Struktur der
Funktionsargumente zu spezifizieren, um mit Hilfe von
Pattern-Matching eine Auswahl zwischen verschiedenen
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.
12
26.10.2009
Einige Funktionen auf Listen
Name
Typ
Beispiel
head
[a] -> a
head [1,2,3] => 1
tail
[a] -> [a]
tail [1,2,3] => [2,3]
length
[a] -> Int
length [1,2,3] => 3
(++)
[a] -> [a] -> [a]
[1,2,3] ++ [1,2,3] => [1,2,3,1,2,3]
(!!)
[a] -> Int -> [a]
[1,2,3,4] !! 2 => 3
take
Int -> [a] -> [a]
take 2 [1,2,3,4] => [1,2]
drop
Int -> [a] -> [a]
drop 2 [1,2,3,4] => [3,4]
13
26.10.2009
Arithmetische Sequenzen
Mit Hilfe des
..
Operators lassen sich in Haskell sehr elegant
Zahlensequenzen erzeugen.
[ 1 .. 5 ]
=>
[1,2,3,4,5]
[ 0, 5 .. 21]
=> [ 0, 5, 10, 15, 20 ]
[ 10, 8 .. 0 ]
=> [ 10, 8, 6, 4, 2, 0 ]
[ 10 .. 1 ]
=> []
[ 1 .. ]
=> unendliche Liste
take 5 [2, 0 .. ]
=> [ 2, 0, -2, -4, -6 ]
14
26.10.2009
Strings
Strings sind Listen von Zeichen
Type-Synomym
type String = [Char]
Syntaktische Abkürzung
[ 'H' , 'e', 'l', 'l', 'o' ]
=>
"Hello"
Haskell ruft implizit am Ende der Auswertung eines Ausdrucks die ShowFunktion an, die aus einem beliebigen Datentyp einen String erzeugt.
…
15
26.10.2009
Listen-Generatoren
Die Syntax von Listengeneratoren in Haskell ist sehr ähnlich zu dem, was wir
für die Definition von Menge in der Mathematik kennen.
Mathematik:
{ x ∈ { 1 .. 20 } | x mod 3 = 0 }
Menge aller Zahlen, die genau durch 3 geteilt werden können
Haskell:
[ x | x <- [1 .. 20], mod x 3 == 0 ]
damit gibt man Haskell die Anweisung eine Liste zu bilden aus allen
Elementen, die genau durch 3 geteilt werden können:
Sollen dabei mehrere Bedingungen erfüllt werden, so müssen diese durch
Komma getrennt sein.
Im Unterschied zu der mathematischen Definition von Menge können HaskellListen sich wiederholende Elemente beinhalten.
…
16
26.10.2009
Currying
In Haskell kann eine Funktion, die zwei oder mehr Argumente
erwartet, als eine Verschachtelung von Funktionen interpretiert
werden, die jeweils nur ein Argument bekommen ( implizites
Currying).
Beispiel:
sum :: Int -> Int -> Int
sum x y = x + y
Diese Definition ermöglicht eine partielle Anwendung wie z.B.
sum 1, die als Ergebnis eine Funktion zurückgibt, die ein
zweites Argument erwartet.
inc :: Int -> Int
inc = (sum 1)
.
17
26.10.2009
Korrekte und Effiziente Lösung von Problemen
Problem
Wesentlicher Teil der
Lösung eines Problems.
Sehr Kreative Phase
Algorithmus
Programmierung oder Codierung
des Algorithmus in einer
bestimmten Programmiersprache.
Einfache Phase
Programm in einer
höheren
Programmiersprache
18
26.10.2009
Algorithmen
Definition von Algorithmus
Ein Algorithmus ist eine präzise, endliche
Verarbeitungsvorschrift zur Lösung eines
Problems.
Ein Algorithmus ist ein Plan zur Lösung eines
Problems mit Hilfe einer endlichen Folge eindeutiger,
ausführbarer Schritte.
Algorithmen sind sprachunabhängig.
19
26.10.2009
Analyse von Algorithmen
Korrektheit
Wichtigste
Eigenschaften bei der
Terminierbarkeit
Analyse von
Algorithmen
- Rechenzeit
Komplexität
- Speicherplatz
- Bandbreite oder
Datentransfer
20
26.10.2009
Analyse von Algorithmen
Rechenzeit
Anzahl der durchgeführten Elementaroperationen in
Abhängigkeit von der Eingabegröße.
Speicherplatz
Maximaler Speicherverbrauch während der
Ausführung des Algorithmus in Abhängigkeit von
der Komplexität der Eingabe.
Bandbreite
Wie groß ist die erforderliche
Datenübertragung?
21
26.10.2009
Analyse von Algorithmen
Charakterisierung unserer Daten
(Eingabegröße)
Rechenzeit
oder
Bestimmung der abstrakten Operationen
(Berechnungsschritte in unserem Algorithmus)
Zeitanalyse
Eigentliche mathematische Analyse, um eine
Funktion in Abhängigkeit zur Eingabegröße zu
finden.
Komplexitätsanalyse
22
26.10.2009
Multiplikation von zwei komplexen Zahlen
i
i
(a+b ) (c+d )
i i i
ac + adi + bci - bd
= ac + ad + bc + bd
=
2
= ( ac - bd ) + ( ad + bc )
i
a, b, c, d
Eingabe:
2 Additionen
(ac – bd), (ad + bc)
Ausgabe:
e
Eine Multiplikation kostet 1 Euro
Eine Summe kostet 1 Cent
,
fi
4 Multiplikationen
Zwei komplexe Zahlen zu
multiplizieren kostet
4,02 є
23
26.10.2009
Algorithmus von Gauß
i
i
(a+b ) (c+d )
2
3
a+b
c+d
ac
bd
r4
r5
3
r4 - r5
r3
r3 = r1 r2 = ac + ad + bc + bd
r3 – r4 – r5 = ac + ad + bc + bd – ac – bd
= ad + bc
5
r3 - r4 - r5
=
1
r1 r2
4
=
2
1
(ac – bd)
, (ad + bc)
i
3 Multiplikationen
5 Summen
Zwei komplexe Zahlen zu
multiplizieren kostet
3,05 є
24
26.10.2009
Zwei Lösungen
multC :: Complex -> Complex -> Complex
multC (a,b) (c,d) = ( a*c - b*d, a*d + b*c )
gaussMultC :: Complex -> Complex -> Complex
gaussMultC (a,b) (c,d) = ( r4 - r5, r3 - r4 - r5)
where
r1 = a+b
r2 = c+d
r3 = r1*r2
r4 = a*c
r5 = b*d
25
26.10.2009
Sieb des Eratosthenes
3. Jahrhundert v. Chr.
Das Sieb des Eratosthenes ist ein sehr bekannter Algorithmus, der für
ein vorgegebenes N alle Primzahlen findet, die kleiner gleich N sind.
Der Algorithmus verwendet ein Feld p aus booleschen Werten, mit dem
Ziel, dem Element p[i] den Wert 1 zuzuweisen, falls i eine Primzahl ist,
und anderenfalls den Wert 0.
Ziel:
P
P
P
P
P
1
2
3
4
5
6
7
8
9
10
11
0
1
1
0
1
0
1
0
0
0
1
P
26
26.10.2009
Sieb des Eratosthenes
Anfang:
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
0
1
1
0
1
1
0
1
1
0
1
1
0
1
1
0
1
1
0
1
1
0
1
1
0
1
1
0
1
1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
0
1
1
0
1
0
1
0
0
1
0
1
0
1
0
0
1
0
1
0
1
0
0
1
27
26.10.2009
Sieb des Eratosthenes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
0
1
1
0
1
0
1
0
0
0
1
0
1
0
0
0
1
0
1
0
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
0
1
1
0
1
0
1
0
0
0
1
0
1
0
0
0
1
0
1
0
0
N
nicht mehr!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
0
1
1
0
1
0
1
0
0
0
1
0
1
0
0
0
1
0
1
0
0
nur bis N/2
noch besser ist nur bis
2
N
28
26.10.2009
Listen
primzahlen
n = sieb [2..n]
where
sieb [] = []
sieb (p:x) = p:sieb[k | k<-x, k `mod` p>0]
primzahlen2
= sieb [2..]
where
sieb (p:x) = p:sieb[k | k<-x, k `mod` p>0]
29
Herunterladen