Listen in Haskell - Otto-von-Guericke

Werbung
Datentyp Liste
Strings
Listenkomprehension
Datentyp Liste
Strings
Listenkomprehension
Gliederung
Algorithmen und Datenstrukturen – Einführung
Listen in Haskell
D. Rösner
Institut für Wissens- und Sprachverarbeitung
Fakultät für Informatik
Otto-von-Guericke Universität Magdeburg
1
Datentyp Liste
2
Strings
3
Listenkomprehension
Winter 2008/2009, 19. Oktober 2008
D. Rösner
AuD 2008/2009 . . .
Datentyp Liste
Strings
Listenkomprehension
D. Rösner
AuD 2008/2009 . . .
Datentyp Liste
Strings
Listenkomprehension
Listen in Haskell:
Primitive Rekursion über Listen
Listen . . . Zusammenfassung beliebig vieler Elemente vom
selben Typ
Darstellung des Listentyp: [<typ>],
z.B.
[Int], [Char], [[Int]], [(Name, Matrnr)], ...
Listen werden – sofern ungleich der leeren Liste [] - durch
Anwendung des Konstruktors ‘:’ (sprich: cons) in
eindeutiger Weise ausgehend von [] aufgebaut
Beispiel:
[4,2,3] == 4:2:3:[] == 4:(2:(3:[]))
auch ‘tail recursion’ genannt
Definition durch
Angabe des Ausgangswerts für [] und
Angabe, wie von Wert für xs auf Wert von (x:xs)
übergegangen wird
Beispiel: Bestimmung der Länge einer Liste
length []
= 0
length (x:xs) = 1 + length xs
‘:’ ist rechts-assoziativ, d.h. x:y:zs == x:(y:zs)
D. Rösner
AuD 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Datentyp Liste
Strings
Listenkomprehension
Datentyp Liste
Strings
Listenkomprehension
Primitive Rekursion über Listen
Rekursion über Listen cont.
Beispiel: Summe der Werte der Listenelemente
Beachte:
length ist polymorph, d.h. auf Listen unterschiedlichen
Typs anwendbar:
length :: [a] -> Int
’wildcard’ in der zweiten Gleichung der Definition möglich,
d.h.
length (_:xs) = 1 + length xs
length ist wie viele andere Funktionen auf Listen im sog.
Standard-Prelude von Haskell bereits vordefiniert
D. Rösner
sum :: [Int] -> Int
sum []
= 0
sum (x:xs) = x + sum xs
Frage: sum [2, 4 .. 11] ,→ . . . ?
sum ist vordefiniert und polymorph
Prelude> :t sum
sum :: Num a => [a] -> a
D. Rösner
AuD 2008/2009 . . .
Datentyp Liste
Strings
Listenkomprehension
Datentyp Liste
Strings
Listenkomprehension
Rekursion über Listen cont.
Der Typ String
Beispiel: Sortieren mit sog. Insertion-Sort
iSort :: [Int] -> [Int]
iSort []
iSort (x:xs)
= []
= ins x (iSort xs)
ins :: Int -> [Int] -> [Int]
ins
ins
|
|
x []
= [x]
x (y:ys)
x<= y
= x:(y:ys)
otherwise = y: ins x ys
D. Rösner
AuD 2008/2009 . . .
AuD 2008/2009 . . .
Spezialfall: Liste aus Zeichen, d.h.
type String = [Char]
alle polymorphen Listenfunktionen können für String
benutzt werden
Ausgabe mit putStr
putStr :: String -> IO ()
Wechsel zwischen Strings und Werten:
show (2 + 3) ==> "5"
umgekehrt:
(read "True") :: Bool ==> True
D. Rösner
AuD 2008/2009 . . .
Datentyp Liste
Strings
Listenkomprehension
Datentyp Liste
Strings
Listenkomprehension
Der Typ String
Darstellung von Listen
alle polymorphen Listenfunktionen können für String
benutzt werden
Prelude> "ein " ++ "konkatenierter String"
...
Prelude> head "wort"
für Listen von Zahlen, Zeichen und anderen
Aufzählungstypen gibt es Kurzschreibweisen
[n .. m] Kurzform für [n,n+1,...,m]
(falls m kleiner als n ist Liste leer)
...
Prelude> tail "wort"
Beispiele:
...
Prelude> length "wort"
...
Prelude> init "wort"
...
[3 .. 9]
[1.2 .. 4.1]
[’f’ .. ’q’]
== [3,4,5,6,7,8,9]
== [1.2,2.2,3.2]
== "fghijklmnopq"
Prelude> last "wort"
...
...
D. Rösner
D. Rösner
AuD 2008/2009 . . .
Datentyp Liste
Strings
Listenkomprehension
AuD 2008/2009 . . .
Datentyp Liste
Strings
Listenkomprehension
Listenkomprehension
Darstellung von Listen
Vorbild: math. Notation für Mengen
Beispiel: Teiler(n) = {i∈Nk i≤n, i Teiler von n}
Variante: die ‘Differenz’ zwischen dem zweiten und dem
ersten Element ergibt die ‘Schrittweite’
Beispiele:
[3,5 .. 14]
[0.0,0.4 .. 2.0]
[’f’,’h’ .. ’q’]
= [3,5,7,9,11,13]
= [0.0,0.4,0.8,1.2,1.6,2.0]
= "fhjlnp"
in Haskell:
teiler :: Int
-> [Int]
teiler n = [ i | i<-[1..n], mod n i == 0]
Liste [1..n] wirkt als Generator
Test mod n i == 0 wählt Elemente aus
mehrere Tests in Form boolescher Ausdrücke möglich
D. Rösner
AuD 2008/2009 . . .
D. Rösner
AuD 2008/2009 . . .
Datentyp Liste
Strings
Listenkomprehension
Datentyp Liste
Strings
Listenkomprehension
Listenkomprehension cont.: Beispiele
Listenkomprehension cont.: Beispiele
(vgl. [Tho99], pp.79)
(vgl. [Tho99], pp.79)
Sei isEven definiert:
Sei ex die Liste [2,4,7]
isEven :: Int -> Bool
[ 2*n | n<-ex] ,→ [4,8,14]
lies: ‘Nimm alle 2*n für n aus der Liste ex’
isEven n = (n ‘mod‘ 2 == 0)
zur Veranschaulichung: Auswertung tabellarisch
n
2*n
=
=
2
4
4
8
[ isEven n | n<-ex] ,→ [True, True, False]
7
14
mehrere Tests möglich
[ 2*n | n<-ex, isEven n, n>3]
D. Rösner
D. Rösner
AuD 2008/2009 . . .
Datentyp Liste
Strings
Listenkomprehension
AuD 2008/2009 . . .
Datentyp Liste
Strings
Listenkomprehension
Listenkomprehension cont.: Beispiele
Listenkomprehension cont.
(vgl. [Tho99], pp.79)
(vgl. [Tho99], pp.79)
links von <- können nicht nur Variable, sondern auch
Muster (pattern) stehen
Beispiel:
zusätzlicher Test:
nur geordnete Paare addieren
addPairs :: [(Int,Int)] -> [Int]
addPairs pairList
= [ n+m | (n,m) <- pairList]
addOrdPairs :: [(Int,Int)] -> [Int]
addOrdPairs pairList
= [ n+m | (n,m) <- pairList, n < m]
Veranschaulichung mit Tabelle:
[ n+m
n
m
n+m
| (n,m) <- [(2,3),(2,1),(7,8)]]
=
2
2
7
=
3
1
8
=
5
3
15
D. Rösner
AuD 2008/2009 . . .
Frage: addOrdPairs [(2,3),(2,1),(7,8)] ,→ . . . ?
D. Rösner
AuD 2008/2009 . . .
Datentyp Liste
Strings
Listenkomprehension
Datentyp Liste
Strings
Listenkomprehension
Listenkomprehension cont.:
Listenkomprehension cont.
(vgl. [Tho99], 17.3)
Syntax: allgemeine Form ist [ e | q1 , ... qk ]
dabei ist jeder der Qualifikatoren qi
entweder ein Generator der Form p <- lExp
mit p Muster und
lExp Ausdruck vom Listentyp
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
mit mehreren Generatoren können Elemente aus zwei
oder mehr Listen kombiniert werden
Beispiel:
pairs :: [a] -> [b] -> [(a,b)]
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 2008/2009 . . .
D. Rösner
Datentyp Liste
Strings
Listenkomprehension
Datentyp Liste
Strings
Listenkomprehension
Listenkomprehension cont.:
Literatur:
pythagoräische Tripel: für welche Tripel (x, y , z) ganzer
Zahlen gilt:
x 2 + y 2 = z2 ?
als Listenkomprehension:
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 ,→ ... ?
D. Rösner
AuD 2008/2009 . . .
AuD 2008/2009 . . .
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 2008/2009 . . .
Herunterladen