• Keine Ergebnisse gefunden

Zustandsabhängige Berechnungen

N/A
N/A
Protected

Academic year: 2022

Aktie "Zustandsabhängige Berechnungen"

Copied!
5
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Praktische Informatik 3: Funktionale Programmierung Vorlesung 11 vom 08.01.2019: Monaden als Berechnungsmuster

Christoph Lüth Universität Bremen Wintersemester 2018/19

17:28:20 2019-01-14 1 [33]

Frohes Neues Jahr!

PI3 WS 18/19 2 [33]

Fahrplan

I Teil I: Funktionale Programmierung im Kleinen I Teil II: Funktionale Programmierung im Großen

I Teil III: Funktionale Programmierung im richtigen Leben

I Aktionen und Zustände

I Monaden als Berechnungsmuster

I Domänenspezifische Sprachen (DSLs)

I Scala — Eine praktische Einführung

I Rückblich & Ausblick

PI3 WS 18/19 3 [33]

Inhalt

I Wie geht das mitIO?

I Das M-Wort

I Monaden als allgemeine Berechnungsmuster

I Fallbeispiel: Auswertung von Ausdrücken

PI3 WS 18/19 4 [33]

Zustandsabhängige Berechnungen

PI3 WS 18/19 5 [33]

Funktionen mit Zustand

I Idee: Seiteneffektexplizitmachen

I Funktionf:ABmit Seiteneffekt inZustandS:

f :A×SB×S

∼= f :ASB×S

I Datentyp:SB×S

I Komposition: Funktionskomposition unduncurry curry :: ((α, β)γ)→α→β→γ uncurry :: (α→β→γ)→ (α, β)γ

PI3 WS 18/19 6 [33]

In Haskell: Zustände explizit

I Zustandstransformer:Berechnung mit Seiteneffekt in Typσ (polymorph überα)

type State σ α=σ→ (α, σ) I Komposition zweier solcher Berechnungen:

comp :: Stateσ α→ (α→ Stateσ β)→ State σ β comp f g = uncurry g◦f

I Trivialer Zustand:

l i f t :: α→ State σ α l i f t = curry id I Lifting von Funktionen:

map :: (α→β)→ State σ α→ Stateσ β map f g = (λ(a , s )→ ( f a , s ))◦g

Zugriff auf den Zustand

I Zustand lesen:

get :: (σ→α)→ State σ α get f s = ( f s , s )

I Zustand setzen:

set :: (σ→σ)→ State σ () set g s = ( ( ) , g s )

(2)

Einfaches Beispiel

I Zähler als Zustand:

type WithCounterα= State Intα

I Beispiel: Funktion, die in Kleinbuchstaben konvertiert undzählt cntToL :: String→WithCounter String

cntToL [ ] = l i f t ""

cntToL (x : xs )

| isUpper x = cntToL xs ‘comp‘

λys→ set (+1) ‘comp‘

λ()→ l i f t (toLower x : ys )

| otherwise = cntToL xs ‘comp‘λys→ l i f t (x : ys )

I Hauptfunktion (verkapseltState):

cntToLower :: String→ ( String , Int ) cntToLower s = cntToL s 0

PI3 WS 18/19 9 [33]

Monaden

PI3 WS 18/19 10 [33]

Monaden als Berechnungsmuster

I IncntToLwerden zustandsabhängige Berechnungen verkettet.

I So ähnlich wie bei Aktionen!

State:

typeStateσ α comp :: Stateσ α

(α→State σ β)→

Stateσ β l i f t :: α→Stateσ α map :: (α→β)→Stateσ α→

Stateσ β

Aktionen:

typeIOα (=) :: IOα

(α→IOβ)→ IOβ return :: α→IOα fmap :: (α→β)→IOα→

IOβ Berechnungsmuster:Monade

PI3 WS 18/19 11 [33]

Monaden als Berechngsmuster

Eine Monade ist:

I mathematisch: durch Operationen und Gleichungen definiert (verallgemeinerte algebraische Theorie)

I als Berechnungsmuster:verknüpfbareBerechnungen mit einem Ergebnis

I inHaskell: durch mehrere Typklassen definierte Operationen mit Eigenschaften

PI3 WS 18/19 12 [33]

Monaden in Haskell

I Aktion auf Funktionen:

class Functor f where

fmap :: (a→ b) → f a → f b fmapbewahrt Identität und Komposition:

fmap id == id

fmap ( f◦g) == fmap f◦fmap g

I Die Eigenschaftensolltengelten, können aber nicht überprüft werden.

I Standard: “Instances of Functor should satisfy the following laws.”

PI3 WS 18/19 13 [33]

Monaden in Haskell

I Verkettung (=) und Lifting (return):

class (Functor m, Applicative m)⇒Monad mwhere (=) :: m a → (a →m b) →m b

return :: a →m a

=ist assoziativ undreturndas neutrale Element:

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

m= (x → k x= h) == (m= k)= h

I Auch diese Eigenschaften können nicht geprüft werden.

I Den syntaktischen Zucker (do-Notation) gibt’s umsonst dazu.

PI3 WS 18/19 14 [33]

Beispiele für Monaden

I Zustandstransformer:ST,State,Reader,Writer

I Fehler und Ausnahmen:Maybe, ’Either

I Mehrdeutige Berechnungen:L i s t,Set

PI3 WS 18/19 15 [33]

Die Reader-Monade

I Aus dem Zustand wird nur gelesen:

dataReader σ α= R {run :: σ→α}

I Instanzen:

instance Functor (Readerσ) where fmap f (R g) = R ( f . g)

instanceMonad (Readerσ) where return a = R ( const a)

R f= g = R $λs→run (g ( f s )) s

I Nur eine elementare Operation:

get :: (σ→α)→ Readerσ α get f = R $λs→ f s

PI3 WS 18/19 16 [33]

(3)

Fehler und Ausnahmen

I Maybeals Monade:

instance Functor Maybewhere fmap f ( Just a) = Just ( f a) fmap f Nothing = Nothing

instance Monad Maybewhere Just a= g = g a Nothing= g = Nothing return = Just

I Ähnlich mitEither

I Berechnungsmodell:Ausnahmen(Fehler)

I f :: α→Maybeβist Berechnung mit möglichem Fehler

I Fehlerfreie Berechnungen werden verkettet

I Fehler (NothingoderLeft x) werden propagiert

PI3 WS 18/19 17 [33]

Mehrdeutigkeit

I L i s tals Monade:

IKönnen wir so nicht hinschreiben, Syntax vordefiniert instance Functor [α] where

fmap = map

instanceMonad [α] where a : as= g = g a ++ ( as= g) [ ]= g = [ ]

return a = [ a ]

I Berechnungsmodell: Mehrdeutigkeit

I f :: α→ [β]ist Berechnung mitmehrerenmöglichen Ergebnissen

IVerkettung: Anwendung der folgenden Funktion aufjedesErgebnis (concatMap)

PI3 WS 18/19 18 [33]

Beispiel

I Berechnung aller Permutationen einer Liste:

1 Ein Element überall in eine Liste einfügen:

i n s :: α→ [α]→ [ [α] ] i n s x [ ] = return [ x ] i n s x (y : ys ) = [ x : y : ys ] ++do

i s ← i n s x ys return $ y : i s

2 Damit Permutationen (rekursiv):

perms :: [α]→ [ [α] ] perms [ ] = return [ ] perms (x : xs ) =do

ps ←perms xs i s ← i n s x ps return i s

PI3 WS 18/19 19 [33]

Der Listenmonade in der Listenkomprehension

I Berechnung aller Permutationen einer Liste:

1 Ein Element überall in eine Liste einfügen:

ins ’ :: α→ [α]→ [ [α] ] ins ’ x [ ] = [ [ x ] ]

ins ’ x (y : ys ) = [ x : y : ys ] ++ map (y : ) ( ins ’ x ys )

2 Damit Permutationen (rekursiv):

perms ’ :: [α]→ [ [α] ] perms ’ [ ] = [ [ ] ]

perms ’ (x : xs ) = [ i s | ps ←perms ’ xs , i s ←ins ’ x ps ]

I Listenkomprehension∼= Listenmonade

PI3 WS 18/19 20 [33]

IO ist keine Magie

PI3 WS 18/19 21 [33]

Implizite vs. explizite Zustände

I Wie funktioniert jetztIO?

I Nachteil vonState: Zustand istexplizit

IKanndupliziertwerden I Daher: Zustandimplizitmachen

IDatentypverkapseln(keinrun)

IZugriff aufStatenur über elementare Operationen

PI3 WS 18/19 22 [33]

Aktionen als Zustandstransformationen

I Idee: Aktionen sindTransformationenauf SystemzustandS I Sbeinhaltet

I Speicher als AbbildungA*V(AdressenA, WerteV)

I Zustand des Dateisystems

I Zustand des Zufallsgenerators I In Haskell: TypRealWorld

I “Virtueller” Typ, Zugriff nur über elementare Operationen

I Entscheidend nurReihenfolgeder Aktionen

Fallbeispiel: Auswertung von

Ausdrücken

(4)

Monaden im Einsatz

I Auswertung von Ausdrücken:

data Expr = Var String

|Num Double

| Plus Expr Expr

| Minus Expr Expr

| Times Expr Expr

| Div Expr Expr

IMögliche Arten von Effekten:

I Partialität (Division durch 0)

I Zustände (für die Variablen)

I Mehrdeutigkeit

I Auswertung ohne Effekte:

eval :: Expr→Double eval (Var _) = 0 eval (Num n) = n

eval ( Plus a b) = eval a+ eval b eval (Minus a b) = eval a−eval b eval (Times a b) = eval a∗ eval b eval (Div a b) = eval a/ eval b

PI3 WS 18/19 25 [33]

Auswertung mit Fehlern

I Partialität durchMaybe-Monade eval :: Expr →Maybe Double eval (Var _) = return 0 eval (Num n) = return n

eval ( Plus a b) =dox← eval a ; y← eval b ; return $ x+ y eval (Minus a b) =dox← eval a ; y← eval b ; return $ x−y eval (Times a b) =dox← eval a ; y← eval b ; return $ x∗y eval (Div a b) =do

x←eval a ; y← eval b ; i f y == 0thenNothingelse Just $ x/y

PI3 WS 18/19 26 [33]

Auswertung mit Zustand

I Zustand durchReader-Monade importReaderMonad

import qualified Data .Map as M type State = M.Map String Double eval :: Expr→Reader State Double eval (Var i ) = get (M. ! i ) eval (Num n) = return n

eval ( Plus a b) =dox← eval a ; y← eval b ; return $ x+ y eval (Minus a b) =dox← eval a ; y← eval b ; return $ x−y eval (Times a b) =dox← eval a ; y← eval b ; return $ x∗ y eval (Div a b) =dox← eval a ; y← eval b ; return $ x/ y

PI3 WS 18/19 27 [33]

Mehrdeutige Auswertung

I Dazu: Erweiterung vonExpr:

dataExpr = Var String

|. . .

| Pick Expr Expr

eval :: Expr → [ Double ] eval (Var i ) = return 0 eval (Num n) = return n

eval ( Plus a b) =dox← eval a ; y← eval b ; return $ x+ y eval (Minus a b) =dox← eval a ; y← eval b ; return $ x−y eval (Times a b) =dox← eval a ; y← eval b ; return $ x∗y eval (Div a b) =dox← eval a ; y← eval b ; return $ x/y eval ( Pick a b) =dox← eval a ; y← eval b ; [ x , y ]

PI3 WS 18/19 28 [33]

Kombination der Effekte

I BenötigtKombinationder Monaden.

I MonadeRes:

I Zustandsabhängig

I Mehrdeutig

I Fehlerbehaftet

data Resσ α= Res { run :: σ→ [Maybeα] }

I Andere Kombinationen möglich:

data Resσ α= Res (σ→Maybe [α] )

data Resσ α= Res (σ→ [α] )

data Resσ α= Res ( [σ→α] )

PI3 WS 18/19 29 [33]

Res: Monadeninstanz

I Functordurch Komposition derfmap:

instance Functor (Resσ)where

fmap f (Res g) = Res $ fmap (fmap f ) . g

IMonadist Kombination instanceMonad (Resσ)where

return a = Res ( const [ Just a ] ) Res f= g = Res $λs→doma← f s

casemaof

Just a→run (g a) s Nothing→return Nothing

PI3 WS 18/19 30 [33]

Res: Operationen

I Zugriff auf den Zustand:

get :: (σ→α)→Resσ α get f = Res $λs→ [ Just $ f s ]

I Fehler:

f a i l :: Resσ α

f a i l = Res $ const [ Nothing ]

I Mehrdeutige Ergebnisse:

j o i n :: α→α→Resσ α

j o i n a b = Res $λs→ [ Just a , Just b ]

PI3 WS 18/19 31 [33]

Auswertung mit Allem

I Im MonadenReskönnen alle Effekte benutzt werden:

typeState = M.Map String Double eval :: Expr →Res State Double eval (Var i ) = get (M. ! i ) eval (Num n) = return n

eval ( Plus a b) =dox←eval a ; y←eval b ; return $ x+ y eval (Minus a b) =dox←eval a ; y←eval b ; return $ x−y eval (Times a b) =dox←eval a ; y←eval b ; return $ x∗y eval (Div a b) =dox←eval a ; y←eval b

i f y == 0then f a i l else return $ x /y eval ( Pick a b) =dox←eval a ; y←eval b ; j o i n x y I Systematische Kombination durchMonadentransformer

IMonade mit Platzhalter für weitere Monaden

PI3 WS 18/19 32 [33]

(5)

Zusammenfassung

I Monaden sindMusterfürBerechnungenmitSeiteneffekten I Beispiele:

I Zustandstransformer (State)

I Fehler und Ausnahmen (Maybe,Either)

I Nichtdeterminismus (L i s t)

I Fallbeispiel Auswertung von Ausdrücken:

I Kombination aus Zustand, Partialität, Mehrdeutigkeit I Grenze: Nebenläufigkeit

PI3 WS 18/19 33 [33]

Referenzen

ÄHNLICHE DOKUMENTE

Auf Grund der Selbsthemmung kann die Querkraft näherungsweise gleich null gesetzt werden. Die Absenkung wird vollständig von der Lösekraft getragen. Tritt beim Lösen

Für Verdichtungsinjektionen, bei denen eine hydraulische Rissbildung durch die hohe Viskosität des Injektionsgutes verhindert wird, werden die Vorgänge um eine

In der Praxis muss ich mich nach Ermittlung der Schusszahl, die nötig ist, um einen Treffer zu erreichen, oft auch noch fragen : «Habe ich überhaupt im vorliegenden Falle Zeit,

(Diese Funktion kann nicht verwendet werden, wenn die Funktion für die N-Basis verwendet wird.) Zum Generieren weiterer Zufallszahlen in Reihe ® drücken. Zum Beenden

Chemische Berechnungen (Stöchiometrie) Lösen Sie mit Ihrer Gruppe die folgenden Aufgaben.. Hilfsmittel:

Hat der Nenner höheren Grad, so wären nacheinander alle Nullstellen des Nenners zu entwickeln. In diesem Fall ist man mit Polynomdivision

lernen den Satz von Pythagoras als zentralen Satz der Geometrie kennen und können diesen anwenden.. Konkret: - Die SuS können den Satz in Worten mit den

Wie gross ist die Breite des Rechtecks, wenn die Flächen beider Figuren gleich gross sind und die Länge des Rechtecks 21 dm misst2. Erstelle eine Skizze im Massstab