K07 Haskell 1. 2. 3. 4. 5. 6. Funktionsdefinitionen ListComprehensions RekursiveFunktionen Funktionen höhererOrdnung AlgebraischeDatentypen undTypklassen Interaktive Programme teilweise basiertaufFolienvonGrahamHutton undPhilipWadler thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 2 BedingteAusdrücke n WieinvielenSprachenhatauchHaskell bedingteAusdrücke: abs :: Int -> Int abs n = if n >= 0 then n else -n n BedingteAusdrückekönnen natürlichauchverschachteltsein: signum :: Int -> Int signum n = if n < 0 then -1 else if n == 0 then 0 else 1 n Beachte:BedingteAusdrückehabenimmer einenelse-Zweig! Warum? thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 3 BedingteAusdrückemitGuards n Guards „|“bieteneinealternativezubedingtenAusdrücken, dieimFallevonvielenFallunterscheidungen besserlesbarist. -- wie zuvor, jedoch unter Verwendung von Guards abs n | n >= 0 = n | otherwise = -n signum n | n < 0 = -1 | n == 0 = 0 | otherwise = 1 n otherwise definiertinPrelude als:otherwise = True thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 4 LokaleDefinitionenmitwhere n Problem:WiekannmanMehrfachauswertungvon Ausdrückenumgehen? f x y | | | y > x*x = ... y == x*x = ... otherwise = ... -- x*x wird u.U. zwei mal berechnet besser: f x y n | y > z = ... | y == z = ... | otherwise = ... where z = x*x -- x*x wird nur ein mal berechnet Beachte:z istnichtausserhalb f sichtbar(nested scope) thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 5 PatternMatching n Allgemein: Technik zursymbolbasierten Verarbeitungvon Strukturen(z.B.DatenoderFunktionen) n Muster wirdbenutztzurIdentifikation (einesTeils)einerStruktur n n n (i) DasMuster„passt“oder passtebennichtaufdaswasgegebenist. D.h.esmusseindeutig definiertsein,wieMusteraussehenkönnen undwann einMuster„passt“. SimplesBeispieleinerFunktion,diePatternMatching bzgl.der Argumentebenutzt: not :: Bool -> Bool not False = True not True = False n FunktionenlassensichhäufigmitHilfevonPatternMatching definieren. thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 6 PatternMatching n EsbestehenoftmehrereMöglichkeiteneineFunktion auf BasisvonPatternMatching zudefinieren,z.B.: (&&) True True False False n (ii) && && && && :: True = False = True = False = Bool -> Bool -> Bool True False False False Wiezuvor,jedochkompakter: (&&) :: Bool -> Bool -> Bool True && True = True _ && _ = False -- _ ist Wildcard die auf jedes -- Argument passt (matcht) thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 7 PatternMatching n (iii) Beachte: n MusterwerdeninderReihenfolgederZeilenabgearbeitet: _ && _ = False -- liefert immer False True && True = True n MusterdürfenVariablennichtwiederholen: b && b = True _ && _ = False -- Error: Conflicting definitions -- for `b' thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 8 PatternMatching – Listenmuster n ListenlassensichrekursivdurchdenListenkompositionsoperator (:) („cons“)erzeugenbzw.darstellen: [1,2,3,4] istäquivalentzu 1 : (2:(3:(4:[]))) Kopf n (i) Restliste Funktionen aufListenlassensichdurch x:xs Muster definieren: head :: [a] -> a head (x:_) = x tail :: [a] -> [a] tail (_:xs) = xs thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 9 PatternMatching – Listenmuster n (ii) Beachte: n x:xs MusterpassennuraufnichtleereListen: > head [] Error Ergo:FunktionenaufListenimmerauchfürdieleereListedefinieren, insofern siesichfürdieleereListeüberhauptdefinieren lassen. n x:xs Muster(undmitanderenOperatorengebildeteMusterlinks von=)müssengeklammertwerden,daFunktionsanwendunghöhere Präzedenzals (:) hat: head :: [a] -> a head x:_ = x -- Parser Error thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 10 PatternMatching – Zahlenmuster n Funktionen aufGanzzahlenkönnen(wieinderMathematik) mitHilfevon n+k Musterndefiniertwerden,wobei n eine Variableund k eineKonstanteist: verworfen pred :: Int -> Int pred (n+1) = n n Beachte: n n pred 0 Error n+k MusterpassennuraufArgumente≥k: Wiezuvorschonerwähnt,mussauch(n+k) geklammertwerden: pred :: Int -> Int head n+1 = n -- Parser Error thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 11 Lambda-Ausdrücke n MankanninHaskell (undanderenSprachen)Funktionen definieren,diekeinenNamenhaben,diealsoanonym sind. Diesebezeichnet manalsλ-Ausdrücke. n Lambda-Ausdrückeentstammendemλ-Kalkül Schreibweise/Beispiel: Lambda-Kalkül λx.x+x Haskell \x -> x+x AnonymeFunktion, diex alsArgumenthatundx+x alsErgebnis. thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 12 Wozubenutztmanλ-Ausdrücke? 1. ZurformalenDarstellungvonCurryfizierten Funktionen: add x y = x+y 2. bedeutet ZurDefinition vonFunktionendieFunktionenalsErgebnishaben: const :: a -> b -> a const x _ = x 1. add = \x -> (\y -> x+y) const :: a -> (b -> a) const x = \_ -> x Umzuvermeiden dassmaneinerFunktion,dienureinmal referenziert wird,einenNamengebenmuss: odds n = map f [0..n-1] where f x = x*2 + 1 Lässtsichvereinfachen zu odds n = map (\x -> x*2 + 1) [0..n-1] thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 13 Sektionen n DabinäreOperatorencurryfizierte Funktionen sind,kann mansieauchpartiellanwenden. DabeiwirdderOperatorbezeichner(anstattinInfix-)ingeklammerterPräfix- o.SuffixSchreibweisebenutzt. Beispiel: > 1+2 3 > (+) 1 2 3 n diesermöglichteseines derArgumentemitin dieKlammerzunehmen > (1+) 2 3 > (+2) 1 3 Definition:Wenn ⊕ einbinärerOperatorist,dannwerden Funktionen derForm(⊕),(x⊕) und(⊕y) Sektionen genannt. thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 14 WozubenutztmanSektionen? n EineReihenützlicherFunktionen lassensichaufeinfacheArt undWeisedurchSektionen definieren. Beispiele: (1+) - Nachfolgerfunktion > (1+) 3 4 (1/) - Reziprokwertfunktion > (1/) 4 0.25 (*2) - Verdopplungsfunktion > (*2) 3 6 (/2) - Halbierungsfunktion > (/2) 1 0.5 thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 K07 Haskell 1. 2. 3. 4. 5. 6. Funktionsdefinitionen ListComprehensions RekursiveFunktionen Funktionen höhererOrdnung AlgebraischeDatentypen undTypklassen Interaktive Programme thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 16 ListComprehensions mitGeneratoren n NotationausderMathematikzurMengenbeschreibung existiertquasianalogauchinHaskell; erzeugtwerdenjedoch Listen(stattMengen). Mathematik: Haskell: { x2 | x ∊ {1, …, 5}} [ x^2 | x <- [1..5]] Generator n MehrereGeneratorenwerdendurchKommagetrennt;z.B.: > [(x,y) | x <- [1,2,3], y <- [4,5]] [(1,4),(1,5),(2,4),(2,5),(3,4),(3,5)] thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 17 AuswirkungderGeneratorreihenfolge n VertauschungderReihenfolge derGeneratorenbewirkt andereReihenfolgederElemente inderListe: > [(x,y) | x <- [1,2,3], y <- [4,5]] [(1,4),(1,5),(2,4),(2,5),(3,4),(3,5)] > [(x,y) | y <- [4,5], x <- [1,2,3]] [(1,4),(2,4),(3,4),(1,5),(2,5),(3,5)] n MehrereGeneratorensindwieverschachtelteSchleifen, wobeiderletzteGeneratordieinnersteSchleifeist. thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 18 Generatorabhängigkeit n EinGeneratorkannVariableneinesanderenGeneratorsder linksvonihmstehtbenutzen. à Abhängigkeit aufGeneratoren > [(x,y) | x <- [1..3], y <- [x..3]] [(1,1),(1,2),(1,3),(2,2),(2,3),(3,3)] ListeallerPaare(x,y)sodassx,y ∊ {1,2,3}und y≥x. thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 19 NocheinBeispiel n Konkatenation derElementeeinerListevonListen: concat :: [[a]] -> [a] concat xss = [x | xs <- xss, x <- xs] Beispiel: > concat [[1,2,3],[4,5],[6]] [1,2,3,4,5,6] thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 20 GeneratorenundGuards n Guards kannmanbenutzen zurweiterenEinschränkung der WertefrühererGeneratoren: > [x | x <- [1..10], even x] [2,4,6,8,10] n Funktion, diefüreineZahlalleihreTeilerberechnet: factors :: Int -> [Int] factors n = [x | x <- [1..n], n `mod` x == 0] > factors 15 [1,3,5,15] thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 21 Beispiel– Primzahltest-undBerechnung n Primzahl:istnurdurch1undsichselbstteilbar. prime :: Int -> Bool prime n = factors n == [1,n] n > prime 15 False > prime 7 True BerechnungallerPrimzahlenvon1bisn mitHilfeeines Generators,einesGuards undunsererprime-Funktion: primes :: Int -> [Int] primes n = [x | x <- [2..n], prime x] > primes 40 [2,3,5,7,11,13,17,19,23,29,31,37] thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 22 StringComprehensions n DaStringsListenvonZeichen(Char)sind,lassensichalle polymorphen Funktionen aufListenauchaufStrings anwenden, z.B.: > zip "abc" [1,2,3,4] [(’a’,1),(’b’,2),(’c’,3)] n > length "abcde" 5 > take 3 "abcde" "abc” AusdemgleichenGrundkannmanListComprehensions zur DefinitionvonFunktionen aufStringsbenutzen, z.B.: lowers :: String -> Int lowers xs = length [x | x <- xs, isLower x] > lowers "Haskell" 6 thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 K07 Haskell 1. 2. 3. 4. 5. 6. Funktionsdefinitionen ListComprehensions RekursiveFunktionen Funktionen höhererOrdnung AlgebraischeDatentypen undTypklassen Interaktive Programme thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 24 (Wiederholung)Rekursion n VieleFunktionenlassensichmitHilfe vonanderenFunktionen definieren, z.B.: -- factorial definiert mit Hilfe von product factorial :: Int -> Int factorial n = product [1..n] n Rekursion:Funktionf definiertmitHilfe vonsichselbst factorial :: Int -> Int factorial 0 = 1 factorial n+1 = (n+1) * factorial n n Beachte:factorial divergiertfürn <0,daAbbruchbedingungniemals erreichtwird: > factorial (-1) Error: Control stack overflow thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 25 RekursiveAuswertungvonfactorial = = = = factorial 3 3 * factorial 2 3 * (2 * factorial 1) 3 * (2 * (1 * factorial 0)) 3 * (2 * (1 * 1)) = = = 3 * (2 * 1) 3 * 2 6 thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 26 RekursionaufListen n RekursionkannnatürlichauchfürdieDefinitionvon Funktionen aufListenverwendet werden. Beispiel: product :: [Int] -> Int product [] = 1 product (n:ns) = n * product ns = = = = = product [2,3,4] 2 * product [3,4] 2 * (3 * product [4]) 2 * (3 * (4 * product [])) 2 * (3 * (4 * 1)) 24 thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 27 WeitereBeispiele n RekursiveVariantederLängeeinerListe: length :: [a] -> Int length [] = 0 length (_:xs) = 1 + length xs n RekursiveVarianteeinerListeinumgekehrter Reihenfolge: reverse :: [a] -> [a] reverse [] = [] reverse (x:xs) = reverse xs ++ [x] thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 28 BeispielQuickSort n (i) QuickSort kanndurchzweiRegelndefiniertwerden: n n LeereListeistbereitssortiert NichtleereListensortiertmanindemmanKopfvonRestliste abspaltetunddann n n n Restliste ≤Kopfrekursivsortiert Restliste >Kopfrekursivsortiert Resultierende sortierteListenanjeweiligeSeitedesKopfesanhängt quickSort :: Ord a => [a] quickSort [] = [] quickSort (x:xs) = quickSort ys where ys = [a | zs = [b | -> [a] ++ [x] ++ quickSort zs a <- xs, a <= x] b <- xs, b > x] thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 29 BeispielQuickSort (ii) q [3,2,4,1,5] q [2,1] q [1] [1] ++ [2] ++ ++ [3] ++ q [] [] q [4,5] q [] ++ [4] ++ [] thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf q [5] [5] 12.Mai2016 K07 Haskell 1. 2. 3. 4. 5. 6. Funktionsdefinitionen ListComprehensions RekursiveFunktionen Funktionen höhererOrdnung AlgebraischeDatentypen undTypklassen Interaktive Programme thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 31 map-Funktion n map wendeteineFunktionaufalleElementeeinerListean undgibteineListederErgebnissezurück. map :: (a -> b) -> [a] -> [b] Beispiel(wendeSuccessor-Funktion an): > map (+1) [1,3,5] [2,4,6] -- Definition mittels List Comprehension map f xs = [f x | x <- xs] -- Definition mittels Rekursion map f [] = [] map f (x:xs) = f x : map f xs thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 32 filter-Funktion n filter selektiertalleElementeeinerListedieeingegebenes Prädikat– eineBoolescheFunktion – erfüllen. filter :: (a -> Bool) -> [a] -> [a] Beispiel(selektiere nurgeradenZahlen): > filter even [1..10] [2,4,6,8,10] -- Definition mittels List Comprehension filter p xs = [x | x <- xs, p x] -- Definition mittels Rekursion filter p [] = [] filter p (x:xs) | p x = x : filter p xs | otherwise = filter p xs thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 33 Faltungsfunktionen n n Sukzessive Faltung(Reduktion)derElementeeinerListeauf genaueinEndelement gemässeinesFaltungsoperators Å . AllgemeinesrekursivesMuster: f [] = v -- beliebiger Wert; meist neutrales -- Element bezüglich Å f (x:xs) = x ⊕ f xs -- von rechts nach links Vonrechtsnachlinks:foldr [1,2,3] (1⊕(2⊕(3⊕v))) n n Vonlinksnachrechts:foldl [1,2,3] Ist ⊕ nichtassoziativ,dann spieltdieRichtungeineRolle! (((v⊕1)⊕2)⊕3) thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 34 BeispielefürFaltungsfunktionen v = 0 Å = + sum [] = 0 sum (x:xs) = x + sum xs v = 1 Å = * product [] = 1 product (x:xs) = x * product xs sum = foldr (+) 0 product = foldr (*) 1 v = True Å = && and [] = True and (x:xs) = x && and xs and = foldr (&&) True v = False Å = || or [] = False or (x:xs) = x || or xs or = foldr (||) False thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 35 Funktionskomposition n Math.Funktionskomposition isteine(einfache) f g FunktionhöhererOrdnung. n InHaskell realisiertdurch(.)-Operator (.) :: (b -> c) -> (a -> b) -> a -> c f n g f g Beispiel(AnzahlWörterdiemiteinemGrossbuchstabe beginnen). import Data.Char capCount :: [Char] -> Int capCount = length . filter (isUpper . head) . words > capCount "Hello there, Mom!" 2 thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 37 WeitereBeispielef.Funktionen höhererOrdnung -- all testet ob jedes Listenelement Prädikat p erfüllt all :: (a -> Bool) -> [a] -> Bool > all even [2,4,6,8,10] all p xs = and [p x | x <- xs] True -- any testet ob irgend ein Listenelement Prädikat p erfüllt any :: (a -> Bool) -> [a] -> Bool > any isSpace "abc def” any p xs = or [p x | x <- xs] True -- selektiert Listenelement solange Prädikat p erfüllt takeWhile :: (a -> Bool) -> [a] -> [a] takeWhile p [] = [] AnalogexistiertdropWhile takeWhile p (x:xs) | p x = x : takeWhile p xs | otherwise = [] > takeWhile isAlpha "abc def” "abc" thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 K07 Haskell 1. 2. 3. 4. 5. 6. Funktionsdefinitionen ListComprehensions RekursiveFunktionen Funktionen höhererOrdnung Algebraische DatentypenundTypklassen Interaktive Programme thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 39 Typdeklarationen(Synonyme) n type bietetdieMöglichkeiteinenneuenNamen(Synonym)füreinen existierenden Typzuvergeben (Listen,Tupel,Funktionen,algebraische Datentypen). Beispiel: type String = [Char] String istjetzteineSynonymfür[Char] n Wirdhauptsächlichverwendet zurVerbesserung derLesbarkeitvon komplexenTypen. -- sei (Int,Int) ein -- Punkt in der Ebene type Pos = (Int,Int) Verwendung origin origin :: Pos = (0,0) left :: Pos -> Pos left (x,y) = (x-1,y) thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 40 WeitereMöglichkeitenf.Typdeklarationen n AnalogzuFunktionenkönnenTypdeklarationenParameter haben: type Pair a = (a,a) Verwendung mult :: Pair Int -> Int mult (m,n) = m*n copy copy x n :: a -> Pair a = (x,x) Verschachtelungmöglich: type Pos = (Int,Int) type Trans = Pos -> Pos n RekursiveDeklarationennichtmöglich: type Tree = (Int,[Tree]) thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 41 AlgebraischeDatentypen n EinalgebraischerDatentypkannmehralseinenKonstruktor (engl. value constructor) habenmitdemsichWertedesTypserzeugenlassen. n WerdenmitdemSchlüsselwortdata deklariert. n Sindvergleichbarmitkontextfreien Grammatiken. Konstruktorseparator Beispiel(ausPrelude): data Bool = False | True Konstruktoren Beispiel2: type type type data typeconstructor Id = Int Title = String Authors = [String] BookInfo = Book Id Title Authors components value constructor thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 42 WertealgebraischerDatentypenerzeugen n Gegeben: data Answer = Yes | No | Unknown n DannkönnenwirwiefolgtdavonGebrauchmachen: answers answers :: [Answer] = [Yes,No,Unknown] -- Liste aller mögl. Antworten flip :: flip Yes = flip No = flip Unknown = Answer -> Answer -- Funktion auf Antworten No Yes Unknown thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 43 StrukturelleÄquivalenzundTypgleichheit n Beachte:AlgebraischeDatentypen mitidentischerStruktur aberunterschiedlichemNamesindnicht vomselbenTyp! Beispiel: -- x, y Koordinaten data Cartesian2D = Cartesian2D Double Double -- Winkel und Abstand data Polar2D = Polar2D Double Double > Cartesian2D (sqrt 2) (sqrt 2) == Polar2D (pi/4) 2 Couldn’t match expected type 'Cartesian2D’ against inferred type 'Polar2D' thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 44 WeiteresBeispielzuKonstruktoren mitParametern(analogBookInfo) n Shape istentwedereinKreismiteinemDurchmesseroder einRechteckmitdenbeidenSeitenlängen: data Shape = Circle Float | Rect Float Float CircleundShapelassensichwie Funktionenauffassen Circle :: Float -> Shape Rect :: Float -> Float -> Shape n Damitlassensichz.B.folgendeFunktionen definieren: square square n :: Float -> Shape = Rect n n area :: Shape -> Float area (Circle r) = pi * r^2 area (Rect x y) = x * y thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 45 Alegebr.DatentypenmitParametern n AnalogzuTypdeklarationen sindauchhierParameter möglich. data Maybe a = Nothing | Just a n Maybe (ausPrelude)erlaubtinsbesonderepartielle Funktionen elegantzudefinieren: safediv :: Int -> Int -> Maybe Int safediv _ 0 = Nothing safediv m n = Just (m `div` n) safehead :: [a] -> Maybe a safehead [] = Nothing safehead xs = Just (head xs) thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 46 Rekursivealgebr.Datentypen n InHaskell kannmanrekursivealgebr.Datentypen definieren. Beispiel:Binärbaum (BaumindemjederKnotengenauzwei Kindknoten hat;m.a.W.BaummitVerzweigungsgrad2) data Tree = Leaf Int | Node Tree Int Tree 5 Anwendung: Node (Node (Leaf 1) 3 (Leaf 4)) 5 (Node (Leaf 6) 7 (Leaf 9)) 7 3 1 4 thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 6 9 12.Mai2016 47 Typklassen n EineTypklassespezifizierteineMengevonFunktionen, die alleInstanzendieserKlasseunterstützen müssen. n DazuwirddasSchlüsselwortclass verwendet n VergleichbarmitInterfacesinJava Achtung: Instanzenmüssen (==),(/=) :: a -> a -> Bool einenderbeidenOperatoren überschreiben(definieren). -- default Implementierung: Ansonstenkommteszueiner x /= y = not (x == y) Endlosschleife wegender x == y = not (x /= y) gegenseitigen Abhängigkeit. Beispiel: class Eq a where TypderOperatorenistdemzufolge(typeinference): (==),(/=) :: Eq a => a -> a -> Bool thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 48 InstanzeinerTypklasseerzeugen n VoneinerTypklasseerzeugtmanmitdemSchlüsselwort instance eineInstanz. n n FallsTypklasseDefault-Implementierungderdefinierten Funktionenbesitzt,mussInstanzdiesenurüberschreiben wennsieumdefiniertwerdensoll. MankannkeineInstanzenvonTypsynonmyen erzeugen. Gegeben: Dann: data Color = Red | Green | Blue instance Eq Color where -- überschreiben von == Red == Red = True Green == Green = True Blue == Blue = True _ == _ = False thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 49 AutomatischeInstanzerzeugung n data bieteteinoptionalesSchlüsselwortderiving bei dessenVerwendung automatischInstanzenfürdie angegebenen Typklassenerzeugtwerden(vomCompiler). n n ProgrammierermussdanndieFunktionenderTypklassennicht mehrselbstdefinieren. DiesistnurfüreineReihevorhandenerTypklassenmöglich: Read,Show,Bounded,Enum,Eq,Ord Beispiel: data Color = Red | Green | Blue deriving (Read, Show, Eq, Ord) thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 K07 Haskell 1. 2. 3. 4. 5. 6. Funktionsdefinitionen ListComprehensions RekursiveFunktionen Funktionen höhererOrdnung AlgebraischeDatentypen undTypklassen InteraktiveProgramme thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 51 InteraktiveProgramme n Mitdenbisherkennengelernten MittelnkönnenwirnurProgramme schreiben, diebeimStartalleArgumenteentgegennehmen, diesodann dieprogrammierteGesamtfunktion berechnenundamEndeeinErgebnis liefern. à InteraktionmitderUmgebungbishernichtmöglich (Tastatur-)Eingaben Argumente Programm (Funktion) Seiteneffekte;mit „puren“Funktionen nichtrealisierbar. Ergebnis (Bildschirm-)Ausgaben thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 52 Lösung n InteraktiveProgrammekönneninHaskell geschrieben werdenaufBasis vonTypendurchdiesich„reine“Ausdrücke unterscheiden lassenvon „unreinen“Aktionen (engl.Actions)welcheSeiteneffekte habendürfen. IO a Typ vonAktionen die,alsErgebnisihrerAusführung, einenWertvomTyp a zurückgeben. IO Char Aktionen dieChar zurückgeben. IO () Aktionen die„nichts“ zurückgebenund demzufolgenurSeiteneffekte habenkönnen. thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 53 Aktionen n Genaugenommenist IO a einTypsynonym: type IO a n n = RealWorld -> (RealWorld, a) RealWorld isteinfingierter (engl.fake)Typ,dessenfingierte WertejeweilseinenaktuellenWeltzustand repräsentieren. AktionensindalsoFunktionendesWeltzustandes, derabgebildetwird aufeinenneuenWeltzustandundeinoptionalesErgebnis(a). n n n (i) DaWeltzustandfiktiv,machtAuswertung imSinneeinerFunktion keinen Sinn: manmussAktionen ausführen! WeltzustandwirdzurCompilezeit sogar„wegoptimiert“.Ergo:Weltzustand existiertnuraufSprachebeneundverursachtkeineKostenzurLaufzeit. IO istgleichzeitigeineInstanzderTypklasseMonad: instance Monad IO thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 54 Aktionen n n n DieeinzigeMöglichkeiteineAktionauszuführen, egalobdirektoderindirekt,geschiehtdurchdas Bindenanmain. (ii) main :: IO a = IO a AktionenkönnennichtausreinenFunktionenaufgerufen werdenà Funktionwürdedamitihre funktionale Eigenschaftverlieren (wegender Seiteneffekte) undwürdezueinerAktion. f IO a Umkehrungmöglich:Aktionenkönnen sehrwohlFunktionenaufrufen. IO a thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf f 12.Mai2016 55 KompositionvonAktionen n n (i) ErfolgtaufBasisvonBindeoperatoren aufmonadischen Typen KompositionzweierAktionen, so,dassdiesesequenziell ausgeführtwerden,wobeidasErgebnisdererstenAktion stillschweigendignoriertwird. (>>) :: Monad m => m a -> m b -> m b Beispiel: putChar '?' >> putChar '!' Zusammengesetzte Aktion,derenAusführung "?!"aufderStandardausgabe ausgibt. putChar :: String -> IO () thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 56 KompositionvonAktionen n (ii) KompositionzweierAktionen, so,dassdiesesequenziell ausgeführtwerden,wobeidasErgebnisdererstenAktionals Eingabederzweitendient. (>>=) :: Monad m => m a -> (a -> m b) -> m b Beispiel: readLn >>= (\a -> print a) Zusammengesetzte Aktion,derenAusführung zuersteineZeilevonderStandardeingabe liest, diesesodannaufderStandardausgabe ausgibt. readLn :: Read a => IO a print :: Show a => a -> IO () thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 57 do-Notation n Benutzungvon>> und>>= wirdschnellschwerlesbar. n Abhilfe:StrukturenaufBasisvondo (Syntactic shugar) Beispiel:LeseeinenStringvonderStandardeingabe BindeErgebnisanVariable getLine :: IO String getLine = do x <- getChar if x == '\n' then Aktionreturn a gibt return [] lediglichErgebnis a else zurückohnedassihre do xs <- getLine Ausführungirgendeine Interaktionbewirkt. return (x:xs) thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 58 Funktioneninnerhalbdo auswerten n WiebettetmanFunktionsauswertung indo-Sequenzen ein? pal.hs main :: IO () Ausdrücke main = do l <- getLine let lrev = reverse l let le = (show . length) l -- show (length l) let el = reverse le putStrLn (l ++ le ++ el ++ lrev) > ./pal Hello, World! Hello, World!1331!dlroW ,olleH thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 59 WeiteresBeispiel n ForderezurEingabeeinesStringsauf,berechnedieLängedes StringsundgibselbigeaufderStandardausgabeaus. main :: IO () main = do putStr "Enter a string: " s <- getLine putStr "The string has " putStr (show (length s)) putStrLn " characters." thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 K07 Haskell ...One lastthing ... thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016 61 ParalleleAusführungnutzen test.hs import Control.Parallel a `par` `pseq` (a + b ausgewertet + c) main = print (a b+ `par` b + c)c -wird print sequentiell where a = ack 3 10 Berechnungvona erfolgt b = fac 1000 parallelzub undc.Sobaldalle c = 2 ^ 1000 dreiberechnetwurdenerfolgt fac 0 = 1 AusgabederSumme(pseq). fac n = n * fac (n-1) ack 0 n = n+1 ack m 0 = ack (m-1) 1 ack m n = ack (m-1) (ack m (n-1)) > ghc –O2 –o test test.hs –threaded -rtsopts > time ./test +RTS –N2 > 4023872600770937735437 ... 652624386837205668077565 > ./test +RTS -N2 1.24s user 0.06s system 149% cpu 0.65 total thorstenmöller - informatik.unibas.ch/lehre/fs16/prog/07-haskell-teilII.pdf 12.Mai2016