Listen in Haskell - Universität Magdeburg

Werbung
Listen in Haskell
Listen in Haskell
Gliederung
Algorithmen und Datenstrukturen I
Listen in Haskell
1
D. Rösner
Institut für Wissens- und Sprachverarbeitung
Fakultät für Informatik
Otto-von-Guericke Universität Magdeburg
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
c
Winter 2009/10, 16. Oktober 2009, 2009/10
D.Rösner
D. Rösner AuD I 2009/10 . . .
Listen in Haskell
D. Rösner AuD I 2009/10 . . .
1
Datentyp Liste
Strings
Listenkomprehension
Listen in Haskell
Listen in Haskell:
2
Datentyp Liste
Strings
Listenkomprehension
Listen in Haskell:
Listen . . . Zusammenfassung beliebig vieler Elemente vom
selben Typ
Darstellung des Listentyp: [<typ>],
Listen werden – sofern ungleich der leeren Liste [] - durch
Anwendung des Konstruktors ‘:’ (sprich: cons) in
eindeutiger Weise ausgehend von [] aufgebaut
z.B.
Beispiel:
[4,2,3] == 4:2:3:[] == 4:(2:(3:[]))
[Int]
[Char]
[[Int]]
[(Name, Matrnr)]
...
D. Rösner AuD I 2009/10 . . .
‘:’ ist rechts-assoziativ, d.h. x:y:zs == x:(y:zs)
4
D. Rösner AuD I 2009/10 . . .
5
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Listen in Haskell
Primitive Rekursion über Listen
Primitive Rekursion über Listen
Beachte:
auch ‘tail recursion’ genannt
Definition durch
length ist polymorph, d.h. auf Listen unterschiedlichen
Typs anwendbar:
Angabe des Ausgangswerts für [] und
Angabe, wie von Wert für xs auf Wert von (x:xs)
übergegangen wird
length :: [a] -> Int
’wildcard’ in der zweiten Gleichung der Definition möglich,
d.h.
Beispiel: Bestimmung der Länge einer Liste
length (_:xs) = 1 + length xs
length []
= 0
length (x:xs) = 1 + length xs
D. Rösner AuD I 2009/10 . . .
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
length ist wie viele andere Funktionen auf Listen im sog.
Standard-Prelude von Haskell bereits vordefiniert
6
D. Rösner AuD I 2009/10 . . .
Datentyp Liste
Strings
Listenkomprehension
Listen in Haskell
Rekursion über Listen cont.
7
Datentyp Liste
Strings
Listenkomprehension
Rekursion über Listen cont.
Beispiel: Sortieren mit sog. Insertion-Sort
Beispiel: Summe der Werte der Listenelemente
iSort :: [Int] -> [Int]
sum :: [Int] -> Int
sum []
= 0
sum (x:xs) = x + sum xs
iSort []
iSort (x:xs)
Frage: sum [2, 4 .. 11] ,→ . . . ?
ins :: Int -> [Int] -> [Int]
= []
= ins x (iSort xs)
sum ist vordefiniert und polymorph
ins
ins
|
|
Prelude> :t sum
sum :: Num a => [a] -> a
D. Rösner AuD I 2009/10 . . .
8
x []
= [x]
x (y:ys)
x<= y
= x:(y:ys)
otherwise = y: ins x ys
D. Rösner AuD I 2009/10 . . .
9
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Listen in Haskell
Der Typ String
Datentyp Liste
Strings
Listenkomprehension
Der Typ String
alle polymorphen Listenfunktionen können für String
benutzt werden
Prelude> "ein " ++ "konkatenierter String"
Spezialfall: Liste aus Zeichen, d.h.
type String = [Char]
...
alle polymorphen Listenfunktionen können für String
benutzt werden
Ausgabe mit putStr
Prelude> head "wort"
...
Prelude> tail "wort"
...
putStr :: String -> IO ()
Prelude> length "wort"
Wechsel zwischen Strings und Werten:
...
show (2 + 3) ==> "5"
Prelude> init "wort"
umgekehrt:
...
(read "True") :: Bool ==> True
Prelude> last "wort"
...
...
D. Rösner AuD I 2009/10 . . .
Listen in Haskell
11
Datentyp Liste
Strings
Listenkomprehension
Listen in Haskell
Darstellung von Listen
12
Datentyp Liste
Strings
Listenkomprehension
Darstellung von Listen
für Listen von Zahlen, Zeichen und anderen
Aufzählungstypen gibt es Kurzschreibweisen
Variante: die ‘Differenz’ zwischen dem zweiten und dem
ersten Element ergibt die ‘Schrittweite’
[n .. m] Kurzform für [n,n+1,...,m]
(falls m kleiner als n ist Liste leer)
Beispiele:
[3,5 .. 14]
[0.0,0.4 .. 2.0]
[’f’,’h’ .. ’q’]
Beispiele:
[3 .. 9]
[1.2 .. 4.1]
[’f’ .. ’q’]
D. Rösner AuD I 2009/10 . . .
== [3,4,5,6,7,8,9]
== [1.2,2.2,3.2]
== "fghijklmnopq"
D. Rösner AuD I 2009/10 . . .
13
= [3,5,7,9,11,13]
= [0.0,0.4,0.8,1.2,1.6,2.0]
= "fhjlnp"
D. Rösner AuD I 2009/10 . . .
14
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Listen in Haskell
Listenkomprehension
Datentyp Liste
Strings
Listenkomprehension
Listenkomprehension cont.: Beispiele
Vorbild: math. Notation für Mengen
(vgl. [Tho99], pp.79)
Beispiel: Teiler(n) = {i∈Nk i≤n, i Teiler von n}
in Haskell:
Sei ex die Liste [2,4,7]
teiler :: Int
[ 2*n | n<-ex] ,→ [4,8,14]
lies: ‘Nimm alle 2*n für n aus der Liste ex’
-> [Int]
teiler n = [ i | i<-[1..n], mod n i == 0]
zur Veranschaulichung: Auswertung tabellarisch
n
2*n
Liste [1..n] wirkt als Generator
Test mod n i == 0 wählt Elemente aus
=
=
2
4
4
8
7
14
mehrere Tests in Form boolescher Ausdrücke möglich
D. Rösner AuD I 2009/10 . . .
Listen in Haskell
D. Rösner AuD I 2009/10 . . .
16
Datentyp Liste
Strings
Listenkomprehension
Listen in Haskell
Listenkomprehension cont.: Beispiele
17
Datentyp Liste
Strings
Listenkomprehension
Listenkomprehension cont.: Beispiele
(vgl. [Tho99], pp.79)
links von <- können nicht nur Variable, sondern auch
Muster (pattern) stehen
(vgl. [Tho99], pp.79)
Sei isEven definiert:
Beispiel:
isEven :: Int -> Bool
addPairs :: [(Int,Int)] -> [Int]
isEven n = (n ‘mod‘ 2 == 0)
addPairs pairList
= [ n+m | (n,m) <- pairList]
[ isEven n | n<-ex] ,→ [True, True, False]
Veranschaulichung mit Tabelle:
mehrere Tests möglich
[ n+m
n
m
n+m
[ 2*n | n<-ex, isEven n, n>3]
D. Rösner AuD I 2009/10 . . .
18
| (n,m) <- [(2,3),(2,1),(7,8)]]
=
2
2
7
=
3
1
8
=
5
3
15
D. Rösner AuD I 2009/10 . . .
19
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Listen in Haskell
Listenkomprehension cont.
Datentyp Liste
Strings
Listenkomprehension
Listenkomprehension cont.:
(vgl. [Tho99], pp.79)
Syntax: allgemeine Form ist [ e | q1 , ... qk ]
dabei ist jeder der Qualifikatoren qi
zusätzlicher Test:
nur geordnete Paare addieren
entweder ein Generator der Form p <- lExp
addOrdPairs :: [(Int,Int)] -> [Int]
mit p Muster und
lExp Ausdruck vom Listentyp
addOrdPairs pairList
= [ n+m | (n,m) <- pairList, n < m]
oder ein Test, d.h. boolescher Ausdruck bExp
wichtig: ein Ausdruck lExp bzw. bExp in qi kann auf die in
q1 bis qi−1 benutzten Variablen verweisen
Frage: addOrdPairs [(2,3),(2,1),(7,8)] ,→ . . . ?
D. Rösner AuD I 2009/10 . . .
Listen in Haskell
20
Datentyp Liste
Strings
Listenkomprehension
D. Rösner AuD I 2009/10 . . .
Listen in Haskell
Listenkomprehension cont.
21
Datentyp Liste
Strings
Listenkomprehension
Listenkomprehension cont.:
(vgl. [Tho99], 17.3)
mit mehreren Generatoren können Elemente aus zwei
oder mehr Listen kombiniert werden
pythagoräische Tripel: für welche Tripel (x, y , z) ganzer
Zahlen gilt:
x 2 + y 2 = z2 ?
Beispiel:
als Listenkomprehension:
pairs :: [a] -> [b] -> [(a,b)]
pyTriple n = [(x,y,z)| x<-[2 .. n],
y<-[x+1 .. n],
z<-[y+1 .. n],
x*x+y*y==z*z]
Frage:
pyTriple 100 ,→ ... ?
pairs xs ys = [ (x,y) | x<-xs , y<-ys ]
pairs [1,2,3] [4,5] ,→
[(1,4),(1,5),(2,4),(2,5),(3,4),(3,5)]
D. Rösner AuD I 2009/10 . . .
22
D. Rösner AuD I 2009/10 . . .
23
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Listen in Haskell
Literatur: I
Datentyp Liste
Strings
Listenkomprehension
Literatur: II
Richard Bird.
Introduction to functional programming using Haskell.
Prentice Hall Europe, 2000.
ISBN 0-13-484346-0; 2nd edition.
Manual M. Chakravarty and Gabriele C. Keller.
An Introduction to Computing with Haskell.
Pearson Education Australia, 2002.
ISBN 1 74009 404 2; also available in German translation.
Simon Thompson.
Haskell - The Craft of Functional Programming.
Addison Wesley Longman Ltd., Essex, 1999.
2nd edition, ISBN 0-201-34275-8; Accompanying Web site:
http://www.cs.ukc.ac.uk/people/staff/sjt/craft2e.
D. Rösner AuD I 2009/10 . . .
24
D. Rösner AuD I 2009/10 . . .
25
Herunterladen