Programmieren in Haskell

Ähnliche Dokumente
Praktische Informatik 3: Funktionale Programmierung Vorlesung 11 vom : Monaden als Berechnungsmuster

Basiskonstrukte von Haskell

Einführung in die funktionale Programmierung

Programmieren in Haskell

Funktionale Programmierung Grundlegende Datentypen

Einführung in die Informatik 2

Programmieren in Haskell

Was bisher geschah. deklarative Programmierung. funktionale Programmierung (Haskell):

Programmierkurs II. Typsynonyme & algebraische Datentypen

Informatik-Seminar Thema: Monaden (Kapitel 10)

Programmieren in Haskell Einstieg in Haskell

WS 2011/2012. Georg Sauthoff 1. October 18, 2011

Fortgeschrittene Funktionale Programmierung mit Haskell

1 - FortProg ist: [ ] objekt-orientiert; [ ] funktional; [ ] logisch; [ ] manchmal nicht auszuhalten

Ein-Ausgabe. 9.1 Zustände und Seiteneffekte

Programmieren in Haskell

Programmieren in Haskell

Kapitel 3: Eine einfache Programmiersprache. Programmieren in Haskell 1

[10] Software Transactional Memory in Haskell, Tortenwurf und Aufgabenblatt 7

Programmtransformationen und Induktion in funktionalen Programmen

Typklassen, Eingabe und Monaden In Haskell

CGI Programmierung mit Ha. Markus Schwarz

Programmieren in Haskell Felder (Arrays)

4.1 Bäume, Datenstrukturen und Algorithmen. Zunächst führen wir Graphen ein. Die einfachste Vorstellung ist, dass ein Graph gegeben ist als

Unendliche Listen und Bäume

Ströme als unendliche Listen in Haskell

Funktionale Programmierung

Monaden in anderen Programmiersprachen

HTk: Ein GUI für Haskell

Funktionale Programmierung mit Haskell

Grundlagen der Informatik 12. Strukturen

Einführung in die Funktionale Programmierung mit Haskell

Programmieren in Haskell

Proseminar: Perlen der Informatik II Haskell List comprehensions & Typklassen

Programmieren in Haskell

Programmieren in Haskell

Programmieren in Haskell Programmiermethodik

Algorithmen und Programmieren 1 Funktionale Programmierung - Musterlösung zu Übung 8 -

Welche Informatik-Kenntnisse bringen Sie mit?

Introduction to Python. Introduction. First Steps in Python. pseudo random numbers. May 2016

Praktische Informatik 3: Funktionale Programmierung Vorlesung 2 vom : Funktionen und Datentypen

Funktionale Programmierung mit Haskell. Jan Hermanns

Praktische Informatik 3: Funktionale Programmierung Vorlesung 4 vom : Typvariablen und Polymorphie

7down Zusatzaufgaben. Mathias Ziebarth und Joachim Breitner. 13. März 2008

Funktionale Programmierung bringt s! Ein Ausflug mit Haskell in die Praxis

Tag 8. Beispiel: Tabellen formatieren

5.1 Mehr Basistypen. (Wie viele Werte kann man mit n Bit darstellen?)

expr :: Expr expr = Mul (Add (Const 3) (Const 4)) (Div (Sub (Const 73) (Const 37)) (Const 6))

ALP I Einführung in Haskell

Zusammenfassung: Programmieren 2 (C#)

C++ Teil 9. Sven Groß. 17. Juni Sven Groß (IGPM, RWTH Aachen) C++ Teil Juni / 17

Tag 7. Pattern Matching und eigene Datentypen

Praktische Informatik 3: Funktionale Programmierung Vorlesung 5 vom : Funktionen Höherer Ordnung I

Hochschule Darmstadt Informatik-Praktikum (INF 1) WS 2015/2016 Wirtschaftsingenieur Bachelor 5. Aufgabe Datenstruktur, Dateieingabe und -ausgabe

Workshop Einführung in die Sprache Haskell

Hochschule Darmstadt Informatik-Praktikum (INF 1) WS 2014/2015 Wirtschaftsingenieur Bachelor 4. Aufgabe Datenstruktur, Dateieingabe und -ausgabe

Einführung in die Funktionale Programmierung mit Haskell

Funktionale Programmierung

Programmieren in Haskell

Übungen zur Vorlesung Funktionale Programmierung. Wintersemester 2012/2013 Übungsblatt 1

Programmierung 1 (Wintersemester 2015/16) Wiederholungstutorium Lösungsblatt 15 (Linearer Speicher, Listen, Bäume)

1 Funktionale vs. Imperative Programmierung

Adressen. Praktikum Funktionale Programmierung Organisation und Überblick. Termine. Studienleistung

Einführung in die Programmierung für NF MI. Übung 04

Übergang von funktionaler zu OOP. Algorithmen und Datenstrukturen II 1

Operatoren für elementare Datentypen Bedingte Anweisungen Schleifen. Operatoren für elementare Datentypen Bedingte Anweisungen Schleifen

Selbststudium OOP7 & ALG2 Auftrag

Algorithmen und Datenstrukturen

VL06: Haskell (Funktionen höherer Ordnung, Currying)

Hochschule Darmstadt Informatik-Praktikum WS 2017/2018 WIng Bachelor 6. Aufgabenblatt Zeiger, verkettete Liste, Dateieingabe und -ausgabe

Informatik I. Informatik I. 7.1 Der let-ausdruck. 7.2 Das Graphik-Paket image.ss. 7.3 Fraktale Bilder. Wiederholte Berechnungen: Der let-ausdruck

Computergrundkenntnisse und Programmieren, WS 07/08, Übung 11: Klassen der Standardbibliothek 2

Einführung in die Funktionale Programmierung mit Haskell

Projekt 3 Variablen und Operatoren

Funktionale Programmierung mit C++

HaskellDB. Datenbank-Features in Haskell Johannes Reiher

Elementare Datentypen in C++

Transkript:

Programmieren in Haskell Monaden Programmieren in Haskell 1

Sequenzierung mit Dollar und Euro Die Atommüll-Metapher Maybe- und Listen-Monaden Return Die do-notation Monaden als Berechnungen Listenbeschreibungen und Monaden State-Monaden Die IO-Monade Was wir heute machen Programmieren in Haskell 2

Dollar i (h (g (f x))) i $ h $ g $ f x Programmieren in Haskell 3

Dollar i (h (g (f x))) i $ h $ g $ f x infixr 0 $ ($) :: (a -> b) -> a -> b f $ x = f x Programmieren in Haskell 3

Euro infixl 0 > ( >) :: a -> (a -> b) -> b x > f = f x i $ h $ g $ f x f x > g > h > i f x > g > h > i Programmieren in Haskell 4

Atommüll-Metapher Abfall-Prozessoren sind eine Metapher für Funktionen. Sie nehmen Atommüll, verarbeiten ihn und spucken Atommüll aus: Programmieren in Haskell 5

Abfall-Container Atommüll ist gefährlich, also wird er verpackt: Programmieren in Haskell 6

bind-roboter Ein bind-roboter entpackt einen Container und steckt den Inhalt (Atommüll) in einen Prozessor: Programmieren in Haskell 7

bind (>>=) container >>= fn = let a = extractwaste container in fn a (>>=) :: m a -> (a -> m b) -> m b Programmieren in Haskell 8

bind (>>=) container >>= fn = let a = extractwaste container in fn a (>>=) :: m a -> (a -> m b) -> m b Mit dem bind-roboter können wir Prozessoren hintereinanderschalten: wasteinacontainer >>= (\a1 -> putincontainer (decompose a1)) >>= (\a2 -> putincontainer (decay a2)) >>= (\a3 -> putincontainer (melt a3)) Programmieren in Haskell 8

Bisherige Metaphern 1. Prozessoren (Funktionen) 2. Atommüll (Eingaben) 3. Container (monadische Werte) 4. Der bind-roboter >>= 5. Fabriken (Monaden) Programmieren in Haskell 9

Die Maybe-Monade Zur Erinnerung der Maybe-Datentyp: data Maybe a = Nothing Just a Programmieren in Haskell 10

Die Maybe-Monade Zur Erinnerung der Maybe-Datentyp: data Maybe a = Nothing Just a Die bind-funktion: container >>= fn = case container of Nothing -> Nothing Just a -> fn a (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b Programmieren in Haskell 10

Die Listen-Monade container >>= fn = case container of [] -> [] xs -> concat (map fn xs) (>>=) :: [a] -> (a -> [b]) -> [b] Programmieren in Haskell 11

Return Was machen wir mit Maschinen, die direkt Atommüll ausgeben ohne ihn vorher in Container zu verpacken? return :: a -> m a Das ist unsere Funktion putincontainer von vorhin. Programmieren in Haskell 12

Return Was machen wir mit Maschinen, die direkt Atommüll ausgeben ohne ihn vorher in Container zu verpacken? return :: a -> m a Das ist unsere Funktion putincontainer von vorhin. Die return-funktion für Maybe: return a = Just a Programmieren in Haskell 12

Return Was machen wir mit Maschinen, die direkt Atommüll ausgeben ohne ihn vorher in Container zu verpacken? return :: a -> m a Das ist unsere Funktion putincontainer von vorhin. Die return-funktion für Maybe: return a = Just a und für Listen: return a = [a] Programmieren in Haskell 12

Die do-notation Monadischer Code wie bisher: wasteinacontainer >>= \a1 -> foo a1 >>= \a2 -> bar a2 >>= \a3 -> baz a3 Programmieren in Haskell 13

Die do-notation Monadischer Code wie bisher: wasteinacontainer >>= \a1 -> foo a1 >>= \a2 -> bar a2 >>= \a3 -> baz a3 Etwas anders geschrieben: wasteinacontainer >>= \a1 -> foo a1 >>= \a2 -> bar a2 >>= \a3 -> baz a3 Programmieren in Haskell 13

Die do-notation Monadischer Code wie bisher: wasteinacontainer >>= \a1 -> foo a1 >>= \a2 -> bar a2 >>= \a3 -> baz a3 Etwas anders geschrieben: wasteinacontainer >>= \a1 -> foo a1 >>= \a2 -> bar a2 >>= \a3 -> baz a3 Und mit syntaktischem Zucker: do a1 <- wasteinacontainer a2 <- foo a1 a3 <- bar a2 baz a3 Programmieren in Haskell 13

Monaden als Berechnungen Unserer bisherige Metapher sah Monaden als Container. Jetzt interpretieren wir Monaden als Berechnungen: >>=: verkettet zwei monadische Berechnungen (lässt die erste Berechnung laufen, füttert das Ergebnis in die zweite Berechung und lässt auch diese laufen) return x: die Berechung, die einfach x als Ergebnis hat Programmieren in Haskell 14

Rechnen mit der Maybe-Monade Beginnen wir mit einem Telefonbuch: phonebook :: [(String,String)] phonebook = [ ("Bob", "01788 665242"), ("Fred", "01624 556442"), ("Alice", "01889 985333"), ("Jane", "01732 187565") ] Programmieren in Haskell 15

Rechnen mit der Maybe-Monade Beginnen wir mit einem Telefonbuch: phonebook :: [(String,String)] phonebook = [ ("Bob", "01788 665242"), ("Fred", "01624 556442"), ("Alice", "01889 985333"), ("Jane", "01732 187565") ] Darin können wir nach Namen und dazu gespeicherten Telefonnummern suchen: lookup :: a -- Schluessel -> [(a, b)] -- Lookup-Tabelle -> Maybe b -- Ergebnis des Lookups Programmieren in Haskell 15

Programmieren in Haskell 16

Beispiel: Prelude> lookup "Bob" phonebook Just "01788 665242" Prelude> lookup "Jane" phonebook Just "01732 187565" Prelude> lookup "Zoe" phonebook Nothing Programmieren in Haskell 16

Kombination von Lookups comb :: Maybe a -> (a -> Maybe b) -> Maybe b comb Nothing _ = Nothing comb (Just x) f = Just $ f x Programmieren in Haskell 17

Kombination von Lookups comb :: Maybe a -> (a -> Maybe b) -> Maybe b comb Nothing _ = Nothing comb (Just x) f = Just $ f x comb ist nichts anderes als der bind-operator (>>=) für Maybe-Berechnungen. Also: gettaxowed :: String -- Name -> Maybe Double -- Steuerschuld gettaxowed name = lookup name phonebook >>= (\number -> lookup number governmentaldatabase) >>= (\registration -> lookup registration taxdatabase) Programmieren in Haskell 17

Kombination von Lookups comb :: Maybe a -> (a -> Maybe b) -> Maybe b comb Nothing _ = Nothing comb (Just x) f = Just $ f x comb ist nichts anderes als der bind-operator (>>=) für Maybe-Berechnungen. Also: gettaxowed :: String -- Name -> Maybe Double -- Steuerschuld gettaxowed name = lookup name phonebook >>= (\number -> lookup number governmentaldatabase) >>= (\registration -> lookup registration taxdatabase) Oder in der do-notation: Programmieren in Haskell 17

gettaxowed name = do number <- lookup name phonebook registration <- lookup number governmentaldatabase lookup registration taxdatabase Programmieren in Haskell 18

Die weiteren Tabellen: governmentaldatabase :: [(String,String)] governmentaldatabase = [ ("01788 665242", "B24869237"), ("01624 556442", "F36636467"), ("01889 985333", "A22121254"), ("01732 187565", "J77848449") ] taxdatabase :: [(String,String)] taxdatabase = [ ("B24869237", "lots of"), ("F36636467", "not so much"), ("A22121254", "gets something back"), ("J77848449", "criminal") ] Programmieren in Haskell 19

do number <- lookup "Bob" phonebook registration <- lookup number governmentaldatabase taxowed <- lookup registration taxdatabase return taxowed => Just "lots of" Programmieren in Haskell 20

do number <- lookup "Bob" phonebook registration <- lookup number governmentaldatabase taxowed <- lookup registration taxdatabase return taxowed => Just "lots of" do number <- lookup "Zoe" phonebook registration <- lookup number governmentaldatabase taxowed <- lookup registration taxdatabase return taxowed Programmieren in Haskell 20

do number <- lookup "Bob" phonebook registration <- lookup number governmentaldatabase taxowed <- lookup registration taxdatabase return taxowed => Just "lots of" do number <- lookup "Zoe" phonebook registration <- lookup number governmentaldatabase taxowed <- lookup registration taxdatabase return taxowed => Nothing Programmieren in Haskell 20

Eigenschaften der Maybe-Monade Die Maybe-Monade repräsentiert Berechnungen, die versagen können Versagen wird propagiert! Programmieren in Haskell 21

Die Listen-Monade Berechnungen in der Listen-Monade reprässentieren null oder mehr gültige Antworten: instance Monad [] where return a = [a] xs >>= f = concat (map f xs) Programmieren in Haskell 22

Tic-Tac-Toe Wir wollen alle Brett-Konfigurationen ausrechnen, die sich nach drei Zügen ergeben können: getnextconfigs :: Board -> [Board] getnextconfigs =... -- details not important tick :: [Board] -> [Board] tick bds = concatmap getnextconfigs bds find3rdconfig :: Board -> [Board] find3rdconfig bd = tick $ tick $ tick [bd] Programmieren in Haskell 23

Tic-Tac-Toe Wir wollen alle Brett-Konfigurationen ausrechnen, die sich nach drei Zügen ergeben können: getnextconfigs :: Board -> [Board] getnextconfigs =... -- details not important tick :: [Board] -> [Board] tick bds = concatmap getnextconfigs bds find3rdconfig :: Board -> [Board] find3rdconfig bd = tick $ tick $ tick [bd] Mit der Listen-Monade: Programmieren in Haskell 23

find3rdconfig :: Board -> [Board] find3rdconfig bd0 = do bd1 <- getnextconfigs bd0 bd2 <- getnextconifgs bd1 bd3 <- getnextconfigs bd2 return bd3 Programmieren in Haskell 24

Listenbeschreibungen und Monaden pythags = [ (x, y, z) x <- [1..], y <- [x..], z <- [y..], x^2 + y^2 == z^2 ] Programmieren in Haskell 25

Listenbeschreibungen und Monaden pythags = [ (x, y, z) x <- [1..], y <- [x..], z <- [y..], x^2 + y^2 == z^2 ] pythags = do x <- [1..] y <- [x..] z <- [y..] guard (x^2 + y^2 == z^2) return (x, y, z) Programmieren in Haskell 25

guard :: Bool -> [()] guard True = [()] guard False = [] Programmieren in Haskell 26

guard :: Bool -> [()] guard True = [()] guard False = [] pythags = let ret x y z = [(x, y, z)] gd x y z = concatmap (\_ -> ret x y z) (guard $ x^2 + y^2 == z^2) doz x y = concatmap (gd x y) [y..] doy x = concatmap (doz x ) [x..] dox = concatmap (doy ) [1..] in dox Programmieren in Haskell 26

start... x 1 2 3......... y 1 2 3 1 2 3 1 2 3........................... z 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 Programmieren in Haskell 27

Seiteneffekte mit der State-Monade Container werden mit einem Ticket gefüttert und geben ihren Inhalt und ein neues Ticket (eine Quittung) aus: Programmieren in Haskell 28

bind in der State-Monade Programmieren in Haskell 29

Input/Output Die IO-Monade ist eine State-Monade, in der der Zustand die komplette Umgebung ist. Dies erlaubt sequentielle Ein-/Ausgabe: f = do putstrln "What is your name?" name <- getline putstrln ("Nice to meet you, " ++ name ++ "!") Programmieren in Haskell 30

Input/Output Die IO-Monade ist eine State-Monade, in der der Zustand die komplette Umgebung ist. Dies erlaubt sequentielle Ein-/Ausgabe: f = do putstrln "What is your name?" name <- getline putstrln ("Nice to meet you, " ++ name ++ "!") Diese Konstruktion legt die Auswertungsreihenfolge fest! Programmieren in Haskell 30

Copyright notice http://en.wikibooks.org/wiki/haskell/understanding_monads http://en.wikibooks.org/wiki/haskell/advanced_monads http://en.wikibooks.org/wiki/haskell/monadplus Programmieren in Haskell 31