Listen in Haskell - Otto-von-Guericke

Werbung
Listen in Haskell
Listen in Haskell
Gliederung
Programmierparadigmen
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
Sommer 2011, 4. April 2011, 2011
D.Rösner
D. Rösner PGP 2011 . . .
Listen in Haskell
D. Rösner PGP 2011 . . .
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 PGP 2011 . . .
‘:’ ist rechts-assoziativ, d.h. x:y:zs == x:(y:zs)
4
D. Rösner PGP 2011 . . .
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 PGP 2011 . . .
Listen in Haskell
Datentyp Liste
Strings
Listenkomprehension
length ist wie viele andere Funktionen auf Listen im sog.
Standard-Prelude von Haskell bereits vordefiniert
D. Rösner PGP 2011 . . .
6
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 PGP 2011 . . .
8
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
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 PGP 2011 . . .
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 PGP 2011 . . .
== [3,4,5,6,7,8,9]
== [1.2,2.2,3.2]
== "fghijklmnopq"
D. Rösner PGP 2011 . . .
13
= [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
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 PGP 2011 . . .
Listen in Haskell
D. Rösner PGP 2011 . . .
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 PGP 2011 . . .
18
| (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
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 PGP 2011 . . .
Listen in Haskell
20
Datentyp Liste
Strings
Listenkomprehension
D. Rösner PGP 2011 . . .
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 PGP 2011 . . .
22
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