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