Listen in Haskell - Universität Magdeburg

Werbung
Listen in Haskell
Programmierparadigmen
Listen in Haskell
D. Rösner
Institut für Wissens- und Sprachverarbeitung
Fakultät für Informatik
Otto-von-Guericke Universität Magdeburg
c
Sommer 2011, 4. April 2011, 2011
D.Rösner
D. Rösner PGP 2011 . . .
1
Listen in Haskell
Gliederung
1
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
D. Rösner PGP 2011 . . .
2
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Listen in Haskell:
Listen . . . Zusammenfassung beliebig vieler Elemente vom
selben Typ
Darstellung des Listentyp: [<typ>],
z.B.
[Int]
[Char]
[[Int]]
[(Name, Matrnr)]
...
D. Rösner PGP 2011 . . .
4
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Listen in Haskell:
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:[]))
‘:’ ist rechts-assoziativ, d.h. x:y:zs == x:(y:zs)
D. Rösner PGP 2011 . . .
5
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Primitive Rekursion über Listen
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
D. Rösner PGP 2011 . . .
6
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Primitive Rekursion über Listen
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 PGP 2011 . . .
7
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Rekursion über Listen cont.
Beispiel: Summe der Werte der Listenelemente
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 PGP 2011 . . .
8
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Rekursion über Listen cont.
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 PGP 2011 . . .
9
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Der Typ String
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 PGP 2011 . . .
11
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Der Typ String
alle polymorphen Listenfunktionen können für String
benutzt werden
Prelude> "ein " ++ "konkatenierter String"
...
Prelude> head "wort"
...
Prelude> tail "wort"
...
Prelude> length "wort"
...
Prelude> init "wort"
...
Prelude> last "wort"
...
...
D. Rösner PGP 2011 . . .
12
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Darstellung von Listen
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)
Beispiele:
[3 .. 9]
[1.2 .. 4.1]
[’f’ .. ’q’]
== [3,4,5,6,7,8,9]
== [1.2,2.2,3.2]
== "fghijklmnopq"
D. Rösner PGP 2011 . . .
13
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Darstellung von Listen
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"
D. Rösner PGP 2011 . . .
14
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Listenkomprehension
Vorbild: math. Notation für Mengen
Beispiel: Teiler(n) = {i∈Nk i≤n, i Teiler von n}
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 PGP 2011 . . .
16
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Listenkomprehension cont.: Beispiele
(vgl. [Tho99], pp.79)
Sei ex die Liste [2,4,7]
[ 2*n | n<-ex] ,→ [4,8,14]
lies: ‘Nimm alle 2*n für n aus der Liste ex’
zur Veranschaulichung: Auswertung tabellarisch
n
2*n
=
=
2
4
4
8
7
14
D. Rösner PGP 2011 . . .
17
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Listenkomprehension cont.: Beispiele
(vgl. [Tho99], pp.79)
Sei isEven definiert:
isEven :: Int -> Bool
isEven n = (n ‘mod‘ 2 == 0)
[ isEven n | n<-ex] ,→ [True, True, False]
mehrere Tests möglich
[ 2*n | n<-ex, isEven n, n>3]
D. Rösner PGP 2011 . . .
18
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Listenkomprehension cont.: Beispiele
(vgl. [Tho99], pp.79)
links von <- können nicht nur Variable, sondern auch
Muster (pattern) stehen
Beispiel:
addPairs :: [(Int,Int)] -> [Int]
addPairs pairList
= [ n+m | (n,m) <- pairList]
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 PGP 2011 . . .
19
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Listenkomprehension cont.
(vgl. [Tho99], pp.79)
zusätzlicher Test:
nur geordnete Paare addieren
addOrdPairs :: [(Int,Int)] -> [Int]
addOrdPairs pairList
= [ n+m | (n,m) <- pairList, n < m]
Frage: addOrdPairs [(2,3),(2,1),(7,8)] ,→ . . . ?
D. Rösner PGP 2011 . . .
20
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Listenkomprehension cont.:
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
D. Rösner PGP 2011 . . .
21
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Listenkomprehension cont.
(vgl. [Tho99], 17.3)
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 PGP 2011 . . .
22
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Listenkomprehension cont.:
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 PGP 2011 . . .
23
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
Literatur: I
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 PGP 2011 . . .
24
Herunterladen