Fortgeschrittene Techniken der Funktionalen Programmierung (WS

Werbung
Fortgeschrittene Techniken der Funktionalen Programmierung
Vorlesung vom 03.11.09:
Mehr über Monaden
Christoph Lüth, Dennis Walter
Universität Bremen
Wintersemester 2009/10
1
Heute gibt’s:
I
Monaden, mehr Monaden, und noch mehr Monaden
I
Die Monaden der Standardbücherei
I
Referenz: http://www.haskell.org/all˙about˙monads/html
2
Fahrplan
I
Teil I: Monaden und fortgeschrittene Typen
I
Einführung, Wiederholung
I
Zustände, Zustandsübergänge und IO
I
Reader/Writer, Nichtdeterminismus, Ausnahmen
I
Monadentransformer
I
Teil II: Fortgeschrittene Datenstrukturen
I
Teil III: Nebenläufigkeit
I
Teil IV: The Future of Programming
3
Die Identitätsmonade
I
Die allereinfachste Monade:
type I d a = a
i n s t a n c e Monad I d where
return a = a
b = f = f b
4
Fehlermonaden
I
Erste Nährung: Maybe
I
Maybe kennt nur Nothing, daher strukturierte Fehler:
data E i t h e r a b = L e f t a | R i g h t b
type E r r o r a
= Either String a
i n s t a n c e Monad ( E i t h e r S t r i n g ) where
( R i g h t a ) = f = f a
( L e f t l ) = f = L e f t l
return b
= Right b
I
Nachteil: Fester Fehlertyp
I
Lösung: Typklassen
5
Die Monade Control.Monad.Error
I
Typklasse Error für Fehler
c l a s s E r r o r a where
noMsg : : a
strMsg : : S t r i n g → a
I
Fehlermonade parametrisiert über e:
c l a s s ( Monad m) ⇒ MonadError e m where
throwError : : e → m a
catchError : : m a → (e → m a) → m a
i n s t a n c e MonadError ( E i t h e r e ) where
throwError = Left
( Left e ) ‘ catchError ‘ handler = handler e
a
‘ catchError ‘
= a
6
Die Zustandsmonade
I
Zustandsübergang als Funktion
newtype S t a t e s a = S t a t e { unwrap : : ( s → ( a , s ) ) }
i n s t a n c e Monad ( S t a t e s ) where
return a
= State $ λs → (a , s )
( S t a t e g ) = f = S t a t e ( u n c u r r y g . unwrap f )
I
Nachteil 1: Zustandsübergang nicht-strikt (insbesondere lazy)!
I
I
Lösung: Strikter Zustandsübergang— Control.Monad.ST
Nachteil 2: Zustandsübergang ≡ Funktion
I
Lösung: Typklassen
7
Die Monad Control.Monad.State
I
Typklasse State für Zustand lesen/schreiben:
c l a s s MonadState m s where
get : : m s
put : : s → m ( )
I
Zustandsmonade parametrisiert über State:
i n s t a n c e MonadState ( S t a t e s ) s where
get
= State $ λs → ( s , s )
put s = S t a t e $ λ → ( ( ) , s )
I
Aber: manchmal liest man nur, manchmal schreibt man nur. . .
8
Die Lesemonade
I
Intuition: Werte der Eingabe e lesen und verabeiten.
I
Lese-Teil der Zustandsmonade
newtype R e a d e r e a = R e a d e r ( e → a )
i n s t a n c e Monad ( R e a d e r e ) where
return a
= R e a d e r $ λe → a
( R e a d e r r ) = f = R e a d e r $
λe → l e t R e a d e r g = f ( r e ) i n
I
Eingabe wird nicht modifiziert.
I
Beispiel: Lesen aus Symboltabelle (Gegenbeispiel: Datei)
g e
9
Die Monade Control.Monad.Reader
I
Wie vorher: Abstraktion der Leseoperationen
I
Neu: Lokaler Zustand
c l a s s MonadReader e m where
ask
:: m e
local :: (e → e) → m a → m a
i n s t a n c e MonadReader ( R e a d e r e ) where
ask
= Reader i d
l o c a l f c = R e a d e r $ λe → r u n R e a d e r c ( f e )
a s k s : : ( MonadReader e m) ⇒ ( e → a ) → m a
a s k s s e l = a s k = r e t u r n . s e l
10
Die Schreibmonade
I
Produziert einen Strom von Werten
I
Kein Zugriff auf geschriebene Werte möglich
I
Beispiel: “Logging”
newtype W r i t e r w a = W r i t e r ( a , [ w ] )
i n s t a n c e Monad ( W r i t e r w) where
return a
= W r i t e r ( a , [] )
( W r i t e r ( a , w) ) = f = l e t W r i t e r ( a ’ , w ’ ) = f a
i n W r i t e r ( a ’ , w++ w ’ )
I
Abstraktion: auch über Listen von Ausgabewerten
11
Die Monade Control.Monad.Writer
I
Typklasse Monoid: Verallgemeinerte Listen
c l a s s ( Monoid
pass
:: m
listen :: m
tell
:: w
instance
pass
listen
tell
w , Monad m) ⇒ MonadWriter w m where
( a , w → w) → m a
a → m ( a , w)
→ m ()
MonadWriter ( W r i t e r w) where
( W r i t e r ( ( a , f ) ,w) ) = W r i t e r ( a , f w)
( W r i t e r ( a , w) )
= W r i t e r ( ( a , w) ,w)
s
= Writer (() , s )
listens
: : ( MonadWriter w m) ⇒
(w → w) → m a → m ( a , w)
l i s t e n s f m = do ( a , w) ← m; r e t u r n ( a , f w)
c e n s o r : : ( MonadWriter w m) ⇒
(w → w) → m a → m a
c e n s o r f m = p a s s $ do a ← m; r e t u r n ( a , f )
12
Die Listenmonade
I
Listen sind Monaden:
i n s t a n c e Monad [] where
m = f
= concatMap f m
return x = [ x ]
fail s
= []
I
Intuition: f :: a→ [b] Liste der möglichen Resultate
I
Reihenfolge der Möglichkeiten relevant?
13
Der Monade Set
I
Data.Set sind Monaden:
i n s t a n c e Monad S e t where
m = f
= S e t . u n i o n s ( S e t . map f m)
r e t u r n x = Set . s i n g l e t o n x
fail s
= S e t . empty
I
Nicht vordefiniert . . .
14
Der Continuationmonade
I
Auswertungskontext wird explizit modelliert.
newtype Cont r a =
Cont { r u n C o n t : : ( ( a → r ) → r ) }
I
r ist der Typ der gesamten Berechnung
I
a→ r ist der momentane Kontext
i n s t a n c e Monad ( Cont r ) where
return a
= Cont $ λk → k a
( Cont c ) = f = Cont $
λk → c ( λa → r u n C o n t ( f a ) k )
15
Control.Monad.Cont
I
callCC: GOTO für funktionale Sprachen
c l a s s ( Monad m) ⇒ MonadCont m where
callCC : : (( a → m b) → m a) → m a
i n s t a n c e MonadCont ( Cont r ) where
c a l l C C f = Cont $
λk → r u n C o n t ( f ( λa → Cont $ λ
I
→ k a )) k
Lieber nicht benutzen!
16
Exkurs: Was ist eigentliche eine Monade?
I
Monade: Konstrukt aus Kategorientheorie
I
Monade ∼
= (verallgemeinerter) Monoid
I
Monade: gegeben durch algebraische Theorien
I
Operationen endlicher (beschränkter) Aritität
I
Gleichungen
I
Beispiele: Maybe, List, Set, State, . . .
I
Monaden in Haskell: computational monads
I
Strukturierte Notation für Berechnungsparadigmen
I
Beispiel: Rechner mit Fehler, Nichtdeterminismus, Zustand, . . .
17
Kombination von Monaden: Das Problem
I
Gegeben zwei Monaden:
c l a s s Monad m1 where . . .
c l a s s Monad m2 where . . .
I
Es gelten weder
i n s t a n c e Monad (m1 (m2 a ) )
i n s t a n c e Monad (m2 (m1 a ) )
I
Problem: Monadengesetze gelten nicht.
I
Lösung: Nächste Vorlesung
18
Zusammenfassung
I
Monaden sind praktische Abstraktion
I
Wir haben kennengelernt:
I
Fehlermonaden: Maybe, Either, MonadError
I
Zustandsmonaden: State, ST, IO
I
Lese/Schreibmonade: ReaderMonad, WriterMonad
I
Nichtdeterminusmus: [a], Data.Set
I
Explizite Sprünge: Continuation
I
Wichtiges Strukturierungsmittel für funktionale Programme
I
Kombination bereitet (noch) Probleme . . .
19
Herunterladen