• Keine Ergebnisse gefunden

Fortgeschrittene Techniken der Funktionalen Programmierung Vorlesung vom 27.10.09: Monads — The Inside Story

N/A
N/A
Protected

Academic year: 2022

Aktie "Fortgeschrittene Techniken der Funktionalen Programmierung Vorlesung vom 27.10.09: Monads — The Inside Story"

Copied!
20
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Fortgeschrittene Techniken der Funktionalen Programmierung Vorlesung vom 27.10.09:

Monads — The Inside Story

Christoph L¨uth, Dennis Walter

Universit¨at Bremen

Wintersemester 2009/10

(2)

Heute in diesem Theater

I Die Geheimnisse der Monaden

I Endlich Zuweisungen

I Flucht aus Alcatraz –IO f¨ur Erwachsene

(3)

Fahrplan

I Teil I: Monaden und fortgeschrittene Typen

I Einf¨uhrung, Wiederholung

I Zust¨ande, Zustands¨uberg¨ange undIO

I Reader/Writer, Nichtdeterminismus, Ausnahmen

I Monadentransformer

I Teil II: Fortgeschrittene Datenstrukturen

I Teil III: Nebenl¨aufigkeit

I Teil IV: The Future of Programming

(4)

Zustands¨ ubergangsmonaden

I Aktionen (IO a) sind keine schwarze Magie.

I Grundprinzip: SystemzustandΣwird explizit behandelt.

f :: a IO b = f :: (a, Σ) (b, Σ) FolgendeInvarianten m¨ussen gelten:

I Systemzustand darfnie dupliziertoder vergessenwerden.

I Auswertungsreihenfolge muß erhalten bleiben.

I KompositionmussInvarianten erhalten Zustands¨ubergangsmonaden

(5)

Zustands¨ ubergangsmonaden

I Typ:

type ST s a = s ( a , s )

a ST s b=a s (b, s)=(a, s) (b, s) Parametrisiert ¨uber Zustands und Berechnungswerta.

I Komposition durch

(=) : : ST s a ( a ST s b ) ST s b

(6)

Komposition von Zustands¨ uberg¨ angen

I Im Prinzip Vorw¨artskomposition:

(=) : : ST s a ( a ST s b ) ST s b

(=) : : ( s ( a , s ) ) ( a s ( b , s ) ) ( s ( b , s ) ) (=) : : ( s ( a , s ) ) ( ( a , s ) ( b , s ) ) ( s ( b , s ) )

I Damit f =g = uncurry g . f.

I Aber:ST kannkein Typsynonym sein

I N¨otig:abstrakter Datentyp um Invarianten zu erhalten

(7)

ST als Abstrakter Datentyp

I Datentyp verkapseln:

newtype ST s a = ST ( s ( a , s ) )

I Hilfsfunktion (Selektor)

unwrap : : ST s a ( s ( a , s ) ) unwrap (ST f ) = f

I Damit ergibt sich

f = g = ST ( u n c u r r y ( unwrap . g ) . unwrap f ) r e t u r n a = ST (λs ( a , s ) )

(8)

Aktionen

I Aktionen: Zustandstransformationen auf der Welt

I TypRealWorld#repr¨asentiert Außenwelt

I Typ hat genau einen Wert realworld #, der nur f¨ur initialen Aufruf erzeugt wird.

I Aktionen:typeIO a = ST RealWorld# a

I Optimierungen:

I ST s adurchin-place-updateimplementieren.

I IO-Aktionen durcheinfachen Aufrufersetzen.

I Compiler darf keine Redexe duplizieren!

I TypIOstelltlediglichReihenfolge sicher.

(9)

Was ist eigentlich eine Monade?

I STmodelliert imperative Konzepte.

I Beobachtung:Andere Konzepte k¨onnen ¨ahnlich modelliertwerden:

I Ausnahmen:f :: a-¿ Maybe bmit Komposition

(=) : : Maybe a ( a Maybe b ) Maybe b J u s t a = f = f a

Nothing = f = Nothing

I Ben¨otigen Typklassen f¨ur Typkonstruktoren. . .

(10)

Konstruktorklassen

I Konstruktorklassen: Typklassen f¨ur Typkonstruktoren (kinds)

I Beispiel:

c l a s s Functor f where

fmap : : ( a b ) ( f a f b )

i n s t a n c e Functor [ ] where −−Kein ’echtes’ Haskell!

fmap f [] = []

fmap f ( x : xs ) = f x : map f xs

I Erweiterungdes Typsystems (bleibtentscheidbar)

I F¨ur ZustandstransformerST:

i n s t a n c e Monad (ST s ) where

f = g = ST ( u n c u r r y ( unwrap . g ) . unwrap f ) r e t u r n a = ST (λs ( a , s ) )

(11)

Monads: The Inside Story

c l a s s Monad m where

(=) : : m a ( a m b ) m b r e t u r n : : a m a

() : : m a m b m b f a i l : : S t r i n g m a p q = p = λ q

f a i l s = e r r o r s

FolgendeGleichungenm¨ussen (sollten) gelten:

return a =k = k a m =return = m

m =(λxk x =h) = (m =k)=h

(12)

Beispiel: Speicher und Referenzen

I Signatur:

type Mem a

i n s t a n c e Mem Monad

I Referenzen sind abstrakt:

type Ref

newRef : : Mem Ref

I Speicher liest/schreibtString:

readRef : : Ref Mem S t r i n g w r i t e R e f : : Ref S t r i n g Mem ( )

(13)

Implementation der Referenzen

Speicher: Liste von Strings, Referenzen: Index in Liste.

type Mem = ST [ S t r i n g ] −−Zustand type Ref = I n t

newRef = ST (λs ( l e n g t h s , s++[ ”” ] ) ) readRef r = ST (λs ( s ! ! r , s ) ) w r i t e R e f r v = ST (λs ( ( ) ,

take r s ++ [ v ]++ drop ( r +1) s ) ) run : : Mem a a

run (ST f )= f s t ( f [] )

(14)

IORef — Referenzen

I Datentyp der Standardb¨ucherei (GHC, Hugs)

import Data . IORef data IORef a

newIORef : : a IO ( IORef a ) readIORef : : IORef a IO a

w r i t e I O R e f : : IORef a a IO ( )

modifyIORef : : IORef a ( a a ) IO ( )

atomicModifyIORef : : IORef a ( a ( a , b ) ) IO b

I Implementation: “echte” Referenzen.

(15)

Beispiel: Referenzen

f a c : : I n t IO I n t

f a c x = do acc newIORef 1 loop acc x where

loop acc 0 = readIORef acc

loop acc n = do t readIORef acc w r i t e I O R e f acc ( t ∗ n ) loop acc ( n1)

(16)

Flucht aus Alcatraz

I Aus demIO-Monaden gibt es keinen Ausweg.

I Im Gegensatz zu z.B.Maybe:

fromMaybe : : a Maybe a a

I Das ist manchmal unpraktisch: Initialisierungen etc.

I F¨urST gibt es

fixST : : ( a ST s a ) ST s a −−Fixpunkt runST : : (f o r a l l s . ST s a ) a −−NB: Typ!

I F¨urIOgibt es . . .

(17)

Unsichere Aktionen

I Signatur:

import System . IO . Unsafe ( unsafePerformIO ) unsafePerformIO : : IO a a

I Warnung: gef¨ahrlich und nichttypsicher!

t e s t : : IORef [ a ]

t e s t = unsafePerformIO $ newIORef []

main = do w r i t e I O R e f t e s t [ 4 2 ] bang readIORef t e s t putStrLn ( bang : : [ Char ] )

(18)

Verwendung von unsafePerformIO

I IO-Aktionen, die nur

I einmaldurchgef¨uhrt werden sollen, und

I von anderen IO-Aktionenunabh¨angigsind

I Beispiel: Konfigurationsdatei lesen

I Alloziierungglobaler Ressourcen (z.B. Referenzen).

I Debugging(traces, logfiles).

I Enjoyresponsibly!

(19)

Benutzung von unsafePerformIO

I Alloziierung globaler Referenzen:

−−— Generate a new identifier.

newId : : IO I n t

newId = atomicModifyIORef r $ λi ( i +1, i ) where r = unsafePerformIO $ newIORef 1

{−# NOINLINE newId #−}

I NOINLINEbeachten — Optimierungen verhindern.

I Debugging:

t r a c e : : S t r i n g a a

t r a c e s x = unsafePerformIO $ putStrLn s r e t u r n x

(20)

Zusammenfassung & Ausblick

I Blick hinter die Kulissen vonIO

I Monaden und andere Kuriosit¨aten

I Referenzen

I unsafePerformIO

I N¨achstes Mal: Mehr Monaden. . .

Referenzen

ÄHNLICHE DOKUMENTE

I Funktionale Sprachen behandeln Zukunftsthemen heute.. Standard ML);. I Continuations (Auswertungskontext

Fortgeschrittene Techniken der Funktionalen Programmierung Vorlesung vom 03.11.09:.. Mehr ¨

I Standard-B¨ ucherei (Monad Template Library) bietet Standard-Monaden als praktischen Bausatz. I

Fortgeschrittene Techniken der Funktionalen Programmierung Vorlesung vom 17.11.09:..

I Beispiel f¨ur induktive, aber nicht freie Datenstruktur. I Kompakte Darstellung, effiziente

I Aber: Haskell Standard-IO blockiert nur den aufrufenden Thread.. IORef a). I Entweder leer oder gef¨ullt mit Wert vom

I Problem: Wie aus Socket oder Kanal lesen wenn beide blockieren. I L¨osung:

Im kritischen Abschnitt schlafengehen, wenn Bedingung nicht erf¨ullt (Lock freigeben!)1. Andere Threads machen Bedingung wahr und melden