K08 Haskell 1. 2. 3. 4. 5. 6. Funktionsdefinitionen ListComprehensions RekursiveFunktionen FunktionenhöhererOrdnung AlgebraischeDatentypenundTypklassen InteraktiveProgramme teilweisebasiertaufFolienvonGrahamHutton undPhilipWadler thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 2 let-Ausdrücke n WieinanderenfunktionalenSprachen(z.B.Scheme,OCaml)bietetauch Haskell dieMöglichkeitinAusdrückenVariableneinzuführen: let y = x * 3 x = 5 in x / y n SinnvollinsbesondereumLesbarkeitzuverbessernund/oder WiederholungeninkomplexerenAusdrückenzuvermeiden: cylinderArea :: (RealFloat a) => a -> a -> a cylinderArea r h = let sideArea = 2 * pi * r * h topArea = pi * r ^2 in sideArea + 2 * topArea thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 3 BedingteAusdrücke n WieinvielenSprachenhatauchHaskell bedingteAusdrücke: abs :: Int -> Int abs n = if n >= 0 then n else -n n BedingteAusdrückekönnennatü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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 4 BedingteAusdrückemitGuards n Guards „|“bieteneinealternativezubedingtenAusdrücken, dieimFallevonvielenFallunterscheidungenbesserlesbarist. -- 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 5 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 | y > z = ... | y == z = ... | otherwise = ... where z = x*x -- x*x wird nur ein mal berechnet n Beachte:z istnichtausserhalb f sichtbar(nested scope) thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 6 PatternMatching n Allgemein:Technikzursymbolbasierten Verarbeitungvon Strukturen(z.B.DatenoderFunktionen) n Muster wirdbenutztzurIdentifikation (einesTeils)einerStruktur n n n (i) DasMuster„passt“oderpasstebennichtaufdaswasgegebenist. D.h.esmusseindeutigdefiniertsein,wieMusteraussehenkönnenundwann 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 7 PatternMatching n EsbestehenoftmehrereMöglichkeiteneineFunktionauf 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 8 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 9 PatternMatching – Listenmuster n ListenlassensichrekursivdurchdenListenkompositionsoperator (:) („cons“)erzeugenbzw.darstellen: [1,2,3,4] istäquivalentzu 1 : (2:(3:(4:[]))) Kopf n (i) Restliste FunktionenaufListenlassensichdurch x:xs Muster definieren: head :: [a] -> a head (x:_) = x tail :: [a] -> [a] tail (_:xs) = xs thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 10 PatternMatching – Listenmuster n (ii) Beachte: n x:xs MusterpassennuraufnichtleereListen: > head [] Error Ergo:FunktionenaufListenimmerauchfürdieleereListedefinieren, insofernsiesichfürdieleereListeüberhauptdefinierenlassen. 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 11 PatternMatching – Zahlenmuster n FunktionenaufGanzzahlenkönnen(wieinderMathematik) mitHilfevon n+k Musterndefiniertwerden,wobei n eine Variableund k eineKonstanteist: verworfen pred :: Int -> Int pred (n+1) = n n Beachte: n n n+k MusterpassennuraufArgumente≥k: pred 0 Error Wiezuvorschonerwähnt,mussauch(n+k) geklammertwerden: pred :: Int -> Int head n+1 = n -- Parser Error thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 12 Lambda-Ausdrücke n MankanninHaskell (undanderenSprachen)Funktionen definieren,diekeinenNamenhaben,diealsoanonym sind. Diesebezeichnetmanalsλ-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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 13 Wozubenutztmanλ-Ausdrücke? 1. ZurformalenDarstellungvonCurryfizierten Funktionen: add x y = x+y 2. bedeutet ZurDefinitionvonFunktionendieFunktionenalsErgebnishaben: const :: a -> b -> a const x _ = x 1. add = \x -> (\y -> x+y) const :: a -> (b -> a) const x = \_ -> x UmzuvermeidendassmaneinerFunktion,dienureinmal referenziertwird,einenNamengebenmuss: odds n = map f [0..n-1] where f x = x*2 + 1 Lässtsichvereinfachenzu odds n = map (\x -> x*2 + 1) [0..n-1] thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 14 Sektionen n DabinäreOperatorencurryfizierte Funktionensind,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 FunktionenderForm(⊕),(x⊕) und(⊕y) Sektionen genannt. thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 15 WozubenutztmanSektionen? n EineReihenützlicherFunktionenlassensichaufeinfacheArt undWeisedurchSektionendefinieren. 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 16 SektionenalsLambda-Expression n SektionensindFunktionen.Esgibtalsoeineäquivalente Lambda-Expression: Beispiele: (1+) \x -> 1 + x (1/) \x -> 1 / x (*2) \x -> x * 2 (/2) \x -> x / 2 thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 K08 Haskell 1. 2. 3. 4. 5. 6. Funktionsdefinitionen ListComprehensions RekursiveFunktionen FunktionenhöhererOrdnung AlgebraischeDatentypenundTypklassen InteraktiveProgramme thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 18 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 19 AuswirkungderGeneratorreihenfolge n VertauschungderReihenfolge derGeneratorenbewirkt andereReihenfolgederElementeinderListe: > [(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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 20 Generatorabhängigkeit n EinGeneratorkannVariableneinesanderenGeneratorsder linksvonihmstehtbenutzen. à AbhängigkeitaufGeneratoren > [(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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 21 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 22 GeneratorenundGuards n Guards kannmanbenutzenzurweiterenEinschrä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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 23 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 24 StringComprehensions n DaStringsListenvonZeichen(Char)sind,lassensichalle polymorphenFunktionenaufListenauchaufStrings anwenden,z.B.: > length "abcde" > zip "abc" [1,2,3,4] [(’a’,1),(’b’,2),(’c’,3)] n 5 > take 3 "abcde" "abc” AusdemgleichenGrundkannmanListComprehensions zur DefinitionvonFunktionenaufStringsbenutzen,z.B.: lowers :: String -> Int lowers xs = length [x | x <- xs, isLower x] > lowers "Haskell" 6 thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 K08 Haskell 1. 2. 3. 4. 5. 6. Funktionsdefinitionen ListComprehensions RekursiveFunktionen FunktionenhöhererOrdnung AlgebraischeDatentypenundTypklassen InteraktiveProgramme thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 26 (Wiederholung)Rekursion n VieleFunktionenlassensichmitHilfevonanderenFunktionen definieren,z.B.: -- factorial definiert mit Hilfe von product factorial :: Int -> Int factorial n = product [1..n] n Rekursion:Funktionf definiertmitHilfevonsichselbst 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 27 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 28 RekursionaufListen n RekursionkannnatürlichauchfürdieDefinitionvon FunktionenaufListenverwendetwerden. 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 29 WeitereBeispiele n RekursiveVariantederLängeeinerListe: length :: [a] -> Int length [] = 0 length (_:xs) = 1 + length xs n RekursiveVarianteeinerListeinumgekehrterReihenfolge: reverse :: [a] -> [a] reverse [] = [] reverse (x:xs) = reverse xs ++ [x] thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 30 BeispielQuickSort n (i) QuickSort kanndurchzweiRegelndefiniertwerden: n n LeereListeistbereitssortiert NichtleereListensortiertmanindemmanKopfvonRestliste abspaltetunddann n n n Restliste≤Kopfrekursivsortiert Restliste>Kopfrekursivsortiert ResultierendesortierteListenanjeweiligeSeitedesKopfesanhä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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 31 BeispielQuickSort (ii) q [3,2,4,1,5] q [2,1] q [1] ++ [2] ++ [1] ++ [3] ++ q [] [] q [4,5] q [] ++ [4] ++ [] thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf q [5] [5] 11.Mai2017 K08 Haskell 1. 2. 3. 4. 5. 6. Funktionsdefinitionen ListComprehensions RekursiveFunktionen FunktionenhöhererOrdnung AlgebraischeDatentypenundTypklassen InteraktiveProgramme thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 33 map-Funktion n map wendeteineFunktionaufalleElementeeinerListean undgibteineListederErgebnissezurück. map :: (a -> b) -> [a] -> [b] Beispiel(wendeSuccessor-Funktionan): > 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 34 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 35 Faltungsfunktionen n n SukzessiveFaltung(Reduktion)derElementeeinerListeauf genaueinEndelementgemä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 Vonlinksnachrechts:foldl [1,2,3] (((v⊕1)⊕2)⊕3) n Ist ⊕ nichtassoziativ,dann spieltdieRichtungeineRolle! thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 36 BeispielefürFaltungsfunktionen v = 0 ⊕ sum [] = 0 sum (x:xs) = x + sum xs = + product [] = 1 product (x:xs) = x * product xs v = 1 ⊕ sum = foldr (+) 0 = * product = foldr (*) 1 v = True ⊕ = && v = False ⊕ = || and [] = True and (x:xs) = x && and xs and = foldr (&&) True or [] = False or (x:xs) = x || or xs or = foldr (||) False thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 38 Funktionskomposition n Math.Funktionskompositionisteine(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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 39 Funktionsapplikationmit$ n „normale“FunktionsapplikationmitLeerzeichenistlinksassoziativ: f a b c -- ist äquivalent zu (((f a) b) c) sum (filter (>10) (map (*2) [2..10])) -- Klammern notwendig n KannmandieseunschönenKlammernloswerden? Lösung:$-Operator: ($) :: (a -> b) -> a -> b ($) f x = f x -- bzw. mit Infixschreibweise: f $ x = f x n $-OperatorhatniedrigstePräzedenz,deshalbisterrechtsassoziativ: f $ g $ h x --äquivalent zu f $ (g $ (h x)) bzw. f (g (h x)) sum (filter (>10) (map (*2) [2..10])) sum $ filter (>10) $ map (*2) [2..10] -- leichter lesbar thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 40 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 K08 Haskell 1. 2. 3. 4. 5. 6. Funktionsdefinitionen ListComprehensions RekursiveFunktionen FunktionenhöhererOrdnung AlgebraischeDatentypenundTypklassen InteraktiveProgramme thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 42 Typdeklarationen(Synonyme) n type bietetdieMöglichkeiteinenneuenNamen(Synonym)füreinen existierendenTypzuvergeben(Listen,Tupel,Funktionen,algebraische Datentypen). Beispiel: type String = [Char] String istjetzteineSynonymfür[Char] n WirdhauptsächlichverwendetzurVerbesserungderLesbarkeitvon 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 43 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 44 AlgebraischeDatentypen n EinalgebraischerDatentypkannmehralseinenKonstruktor (engl. value constructor) habenmitdemsichWertedesTypserzeugenlassen. n WerdenmitdemSchlüsselwortdata deklariert. n SindvergleichbarmitkontextfreienGrammatiken. 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 45 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 46 StrukturelleÄquivalenzundTypgleichheit n Beachte:AlgebraischeDatentypenmitidentischerStruktur 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 47 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.folgendeFunktionendefinieren: 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 48 Alegebr.DatentypenmitParametern n AnalogzuTypdeklarationensindauchhierParameter möglich. data Maybe a = Nothing | Just a n Maybe (ausPrelude)erlaubtinsbesonderepartielle Funktionenelegantzudefinieren: 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 49 Alegebr.DatentypenmitParametern n ParametrisierteWertkonstruktoren (value constructors)sind auchFunktionen. Nothing :: Maybe a Just 10 :: Maybe Int Just :: a -> Maybe a n Deshalbkannmansieentsprechendeinsetzen: map Just [1..5] [Just 1, Just 2, Just 3, Just 4, Just 5] thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 50 Rekursivealgebr.Datentypen n InHaskell kannmanrekursivealgebr.Datentypendefinieren. 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/fs17/prog/08-haskell-teilII.pdf 6 9 11.Mai2017 51 Typklassen n EineTypklassespezifizierteineMengevonFunktionen,diealleInstanzen dieserKlasseunterstützenmüssen. n DazuwirddasSchlüsselwortclass verwendet n n RealisierenadhocPolymorphiebzw.ÜberladenvonVerhalten GrobgesagtvergleichbarmitInterfacesinJava Beispiel: class Eq a where (==),(/=) :: a -> a -> Bool -- default Implementierung: x /= y = not (x == y) x == y = not (x /= y) Achtung: Instanzenmüssen einenderbeidenOperatoren überschreiben(definieren). Ansonstenkommteszueiner Endlosschleifewegender gegenseitigenAbhängigkeit. TypderOperatorenistdemzufolge(typeinference): (==),(/=) :: Eq a => a -> a -> Bool thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 52 Typklassen– Beispiele n EinigederamhäufigstenverwendetenTypklasseninHaskell: Num + - * abs signum negate etc. Fractional / recip Integral div mod etc. Show show :: a -> String Ord < <= > >= max min Enum succ pred thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 53 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 54 AutomatischeInstanzerzeugung n data bieteteinoptionalesSchlüsselwortderiving bei dessenVerwendungautomatischInstanzenfürdie angegebenenTypklassenerzeugtwerden(vomCompiler). n n ProgrammierermussdanndieFunktionenderTypklassennicht mehrselbstdefinieren. DiesistnurfüreineReihevorhandenerTypklassenmöglich,deren Definition„trivial“übertragenwerdenkann: Read,Show,Bounded,Enum,Eq,Ord Beispiel: data Color = Red | Green | Blue deriving (Read, Show, Eq, Ord) thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 K08 Haskell 1. 2. 3. 4. 5. 6. Funktionsdefinitionen ListComprehensions RekursiveFunktionen FunktionenhöhererOrdnung AlgebraischeDatentypenundTypklassen InteraktiveProgramme thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 56 InteraktiveProgramme n MitdenbisherkennengelerntenMittelnkönnenwirnurProgramme schreiben,diebeimStartalleArgumenteentgegennehmen,diesodann dieprogrammierteGesamtfunktionberechnenundamEndeeinErgebnis liefern. à InteraktionmitderUmgebungbishernichtmöglich (Tastatur-)Eingaben Argumente Programm (Funktion) Seiteneffekte;mit „puren“Funktionen nichtrealisierbar. Ergebnis (Bildschirm-)Ausgaben thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 57 Lösung n InteraktiveProgrammekönneninHaskell geschriebenwerdenaufBasis vonTypendurchdiesich„reine“Ausdrückeunterscheidenlassenvon „unreinen“Aktionen (engl.Actions)welcheSeiteneffektehabendürfen. IO a Typ vonAktionendie,alsErgebnisihrerAusführung, einenWertvomTyp a zurückgeben. IO Char AktionendieChar zurückgeben. IO () Aktionendie„nichts“ zurückgebenund demzufolgenurSeiteneffektehabenkönnen. thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 58 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,machtAuswertungimSinneeinerFunktionkeinenSinn: manmussAktionenausführen! WeltzustandwirdzurCompilezeit sogar„wegoptimiert“.Ergo:Weltzustand existiertnuraufSprachebeneundverursachtkeineKostenzurLaufzeit. IO istgleichzeitigeineInstanzderTypklasseMonad: instance Monad IO thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 59 Aktionen- Beispiele putStr :: String -> IO () (ii) -- gibt String auf stdout aus putStrLn :: String -> IO () -- gibt String auf stdout aus mit Zeilenumbruch getLine :: IO String -- liest Zeile (fortlaufende Zeichen bis Zeilenumbruch) von stdin print :: Show a => a –> IO () -- gibt "druckbaren" Wert auf stdout aus readLn :: Read a => IO a -- liest "parsbaren" Wert aus Zeile an stdin thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 60 Aktionen n n n DieeinzigeMöglichkeiteineAktionauszuführen, egalobdirektoderindirekt,geschiehtdurchdas Bindenanmain. (iii) main :: IO a = IO a AktionenkönnennichtausreinenFunktionenaufgerufenwerdenà Funktionwürdedamitihre funktionale Eigenschaftverlieren(wegender Seiteneffekte)undwürdezueinerAktion. f IO a Umkehrungmöglich:Aktionenkönnen sehrwohlFunktionenaufrufen. IO a thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf f 11.Mai2017 61 KompositionvonAktionen n n (i) ErfolgtaufBasisvonBindeoperatorenaufmonadischen Typen KompositionzweierAktionen,so,dassdiesesequenziell ausgeführtwerden,wobeidasErgebnisdererstenAktion stillschweigendignoriertwird. (>>) :: Monad m => m a -> m b -> m b Beispiel: putChar '?' >> putChar '!' ZusammengesetzteAktion,derenAusführung "?!"aufderStandardausgabeausgibt. putChar :: String -> IO () thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 62 KompositionvonAktionen n (ii) KompositionzweierAktionen,so,dassdiesesequenziell ausgeführtwerden,wobeidasErgebnisdererstenAktionals Eingabederzweitendient. (>>=) :: Monad m => m a -> (a -> m b) -> m b Beispiel: readLn >>= (\a -> print a) ZusammengesetzteAktion,derenAusführung zuersteineZeilevonderStandardeingabeliest, diesesodannaufderStandardausgabeausgibt. readLn :: Read a => IO a print :: Show a => a -> IO () thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 63 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 64 Funktioneninnerhalbdo auswerten n WiebettetmanFunktionsauswertungindo-Sequenzenein? 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 65 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 K08 Haskell ...One lastthing ... thorstenmöller- informatik.unibas.ch/lehre/fs17/prog/08-haskell-teilII.pdf 11.Mai2017 67 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/fs17/prog/08-haskell-teilII.pdf 11.Mai2017