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