Programare declarativa - Monade Standardold.unibuc.ro/~ileustean/files/13-monade-standard.pdf ·...

25
Programare declarativ ˘ a 1 Monade Standard Traian Florin S , erb ˘ anut , ˘ a Ioana Leus , tean Departamentul de Informatic ˘ a, FMI, UB [email protected] [email protected] 1 bazat pe P. Wadler, The essence of functional programming s , i pe cursul Informatics !: Functional Programming de la University of Edinburgh Traian Florin S , erb ˘ anut , ˘ a Ioana Leus , tean (UB) PD—Monade 1 / 25

Transcript of Programare declarativa - Monade Standardold.unibuc.ro/~ileustean/files/13-monade-standard.pdf ·...

Programare declarativa1

Monade Standard

Traian Florin S, erbanut,aIoana Leus, tean

Departamentul de Informatica, FMI, [email protected]

[email protected]

1bazat pe P. Wadler, The essence of functional programming s, i pecursul Informatics !: Functional Programming de la University of Edinburgh

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 1 / 25

Evaluare cu efecte laterale

Evaluare cu efecte laterale

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 2 / 25

Evaluare cu efecte laterale Sintaxa abstracta

Lambda calcul cu întregiSintaxa

type Name = String

data Term = Var Name| Con Integer| Term : + : Term| Lam Name Term| App Term Term

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 3 / 25

Evaluare cu efecte laterale Sintaxa abstracta

Exemplu

λ-expresia (λx.x + x)(10 + 11)

este definita astfel:

pgm : : Termpgm = App

(Lam " x " ( ( Var " x " ) : + : ( Var " x " ) ) )( ( Con 10) : + : (Con 11) )

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 4 / 25

Evaluare cu efecte laterale Sintaxa abstracta

Valori

data Value = Num Integer| Fun ( Value −> M Value )| Wrong

instance Show Value whereshow (Num x ) = show xshow ( Fun _ ) = "< func t i on >"show Wrong = "<wrong>"

Observat,ii:

Vom interpreta termenii în valori (M Value), unde M este o monada;variind M se obt,in comportamente diferite;

Wrong reprezinta o eroare, de exemplu adunarea unor valori care nusunt numere sau aplicarea unui termen care nu e funct,ie.

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 5 / 25

Evaluare cu efecte laterale Sintaxa abstracta

Medii de evaluare s, i evaluariInterpretarea termenilor în monada M

type Environment = [ ( Name, Value ) ]

i n t e r p : : Term −> Environment −> M Valuei n t e r p ( Var x ) env = lookupM x envi n t e r p (Con i ) _ = return $ Num ii n t e r p (Lam x e ) env = return $

Fun $ \ v −> i n t e r p e ( ( x , v ) : env )

lookupM : : Name −> Environment −> M ValuelookupM x env = case lookup x env of

Just v −> return vNothing −> return Wrong

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 6 / 25

Evaluare cu efecte laterale Sintaxa abstracta

EvaluareInterpretarea adunarii în monada M

i n t e r p ( t1 : + : t2 ) env = dov1 <− i n t e r p t1 envv2 <− i n t e r p t2 envadd v1 v2

add : : Value −> Value −> M Valueadd (Num i ) (Num j ) = return (Num $ i + j )add _ _ = return Wrong

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 7 / 25

Evaluare cu efecte laterale Sintaxa abstracta

EvaluareInterpretarea aplicarii funct,iilor în monada M

i n t e r p (App t1 t2 ) env = dof <− i n t e r p t1 envv <− i n t e r p t2 envapply f v

apply : : Value −> Value −> M Valueapply ( Fun k ) v = k vapply _ _ = return Wrong

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 8 / 25

Evaluare cu efecte laterale Sintaxa abstracta

Testarea interpretorului

t e s t : : Term −> Stringt e s t t = showM $ i n t e r p t [ ]

unde

showM : : Show a => M a −> String

este o funct,ie definita pentru fiecare monada M în parte, i.e. pentru fiecaretip de efecte laterale dorit.

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 9 / 25

Evaluare cu efecte laterale Sintaxa abstracta

Interpretare în monada Identitate

type M a = I d e n t i t y a

showM : : Show a => M a −> StringshowM = show . r u n I d e n t i t y

Unde monada Identity captureaza transformarea identitate:

newtype I d e n t i t y a = I d e n t i t y { r u n I d e n t i t y : : a }instance Monad I d e n t i t y where

return = I d e n t i t ym >>= k = k ( r u n I d e n t i t y m)

Observat,ie:runIdentity :: Identity a −> aObt,inem interpretorul standard discutat în cursurile trecute

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 10 / 25

Evaluare cu efecte laterale Sintaxa abstracta

Interpretare în monada Identitate

type M a = I d e n t i t y a

showM : : Show a => M a −> StringshowM = show . r u n I d e n t i t y

pgm : : Termpgm = App

(Lam " x " ( ( Var " x " ) : + : ( Var " x " ) ) )( ( Con 10) : + : (Con 11) )

* Var0> t e s t pgm" 42 "

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 11 / 25

Evaluare cu efecte laterale Sintaxa abstracta

Interpretare în monada Optiune

Putem renunt,a la valoarea Wrong folosind monada Maybe

type M a = Maybe a

showM : : Show a => M a −> StringshowM ( Just a ) = show ashowM Nothing = "<wrong>"

Putem acum înlocui rezultatele Wrong cu Nothing

lookupM x env = case lookup x env ofJust v −> return vNothing −> Nothing

add (Num i ) (Num j ) = return (Num $ i + j )add _ _ = Nothingapply ( Fun k ) v = k vapply _ _ = Nothing

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 12 / 25

Evaluare cu efecte laterale Sintaxa abstracta

Interpretare în monada Either String

Putem nuant,a erorile folosind monada Either String

type M a = Either String ashowM ( Left s ) = " Er ro r : � " ++ sshowM ( Right a ) = " Success : � " ++ show a

Putem acum înlocui rezultatele Wrong cu valori Left

lookupM x env = case lookup x env ofJust v −> return vNothing −> Left ( " unbound� v a r i a b l e� " ++ x )

add (Num i ) (Num j ) = return $ Num $ i + jadd v1 v2 = Left

( " should�be�numbers : � " ++ show v1 ++ " ,� " ++ show v2 )apply ( Fun k ) v = k vapply v _ = Left ( " should�be� f u n c t i o n : � " ++ show v )

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 13 / 25

Evaluare cu efecte laterale Sintaxa abstracta

Interpretare în monada Either String

type M a = Either String ashowM ( Left s ) = " Er ro r : � " ++ sshowM ( Right a ) = " Success : � " ++ show a

pgm = App(Lam " x " ( ( Var " x " ) : + : ( Var " x " ) ) )( ( Con 10) : + : (Con 11) )

* Var2> t e s t pgm" Success : 42 "

pgmE = App ( Var " x " ) ( ( Con 10) : + : (Con 11) )

* Var2> t e s t pgmE" Er ro r : unbound v a r i a b l e x "

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 14 / 25

Evaluare cu efecte laterale Sintaxa abstracta

Monada StareControl.Monad.State

newtype State s a = State { runState : : s −> ( a , s ) }

instance Monad ( State s ) wherereturn x = State ( \ s −> ( x , s ) )m >>= k = State ( \ s −>

l e t ( x , s ’ ) = runState m sin runState ( k x ) s ’

get : : State s s −− produce starea curentaget = State ( \ s −> ( s , s ) )

put : : s −> State s ( ) −− schimba starea curentaput s = State ( \ _ −> ( ( ) , s ) )

modify : : ( s −> s ) −> State s ( ) −− modfica s tareamodify f = State ( \ s −> ( ( ) , f s ) )

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 15 / 25

Evaluare cu efecte laterale Sintaxa abstracta

Interpretare în monada StareAdaugarea unui contor de instruct,iuni

data Term = . . . | Count

type M a = State Integer ashowM ma = show a ++ " \ n " ++ " Count : � " ++ show s

where ( a , s ) = runState ma 0

t i c kS = modify (+1)

add (Num i ) (Num j ) = t i c kS >> return (Num $ i + j )add _ _ = return Wrong

apply ( Fun k ) v = t i c kS >> k vapply _ _ = return Wrong

Iar evaluarea lui Count se face astfel:

i n t e r p Count _ = get >>= ( \ i −> return $ Num i )

−−do−− i <− get−− r e t u r n (Num i )

lookupM : : Name −> Environment −> M ValuelookupM x env = case lookup x env of

Just v −> return vNothing −> return Wrong

add : : Value −> Value −> M Valueadd (Num i ) (Num j ) = t i c kS >> return (Num $ i + j )add _ _ = return Wrong

apply : : Value −> Value −> M Valueapply ( Fun k ) v = t i c kS >> k vapply _ _ = return Wrong

t e s t : : Term −> Stringt e s t t = showM $ i n t e r p t [ ]

pgmW : : TermpgmW = App

(Lam " x " ( ( Var " x " ) : + : ( Var " x " ) ) )( ( Con 10) : + : (Con 11) )

main = putStrLn $ t e s t pgmW

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 16 / 25

Evaluare cu efecte laterale Sintaxa abstracta

Interpretare în monada Stare

data Term = . . . | Count

type M a = State Integer ashowM ma = show a ++ " \ n " ++ " Count : � " ++ show s

where ( a , s ) = runState ma 0

pgm : : Termpgm = App

(Lam " x " ( ( Var " x " ) : + : ( Var " x " ) ) )( ( Con 10) : + : (Con 11) )

* Var3> t e s t pgm" 42\ nCount : 3 "

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 17 / 25

Evaluare cu efecte laterale Sintaxa abstracta

Monada WriterControl.Monad.Writer

Este folosita pentru a acumula (logging) informatie produsa în timpulexecut,iei

newtype Wr i te r w a = Wr i t e r { runWr i te r : : ( a , w) }

instance Monoid w => Monad ( Wr i t e r w) wherereturn x = Wr i t e r ( x , mempty )ma >>= k = Wr i t e r $

l e t ( x , w) = runWr i te r ma( x ’ , w ’ ) = runWr i te r ( k x )

in ( x ’ , w ‘mappend ‘ w ’ )

t e l l : : w −> Wr i te r w ( )t e l l w = Wr i t e r ( ( ) , w)

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 18 / 25

Evaluare cu efecte laterale Sintaxa abstracta

Interpretare în monada WriterAdaugarea unei instruct,iuni de afis, are

data Term = . . . | Out Term

type M a = Wr i t e r String a

showM : : Show a => M a −> StringshowM ma = " Output : � " ++ w ++ " \ nValue : � " ++ show a

where ( a , w) = runWr i te r ma

i n t e r p ( Out t ) env = dov <− i n t e r p t envt e l l (show v ++ " ; � " )return v

Out t se evalueaza la valoarea lui tcu efectul lateral de a adauga valoarea la s, irul de ies, ire.

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 19 / 25

Evaluare cu efecte laterale Sintaxa abstracta

Interpretare în monada Writer

data Term = . . . | Out Term

type M a = Wr i t e r String a

showM : : Show a => M a −> StringshowM ma = " Output : � " ++ w ++ " \ nValue : � " ++ show a

where ( a , w) = runWr i te r ma

pgm : : Termpgm = App

(Lam " x " ( ( Var " x " ) : + : ( Var " x " ) ) )( ( Con 10) : + : (Con 11) )

* Var4> t e s t pgm" Output : \ nValue : 42 "

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 20 / 25

Evaluare cu efecte laterale Sintaxa abstracta

Interpretare în monada listelorAdaugarea unei instruct,iuni nedeterministe

data Term = . . . | Amb Term Term | F a i l

type M a = [ a ]

showM : : Show a => M a −> StringshowM = show

i n t e r p F a i l _ = [ ]i n t e r p (Amb t1 t2 ) env = i n t e r p t1 env ++ i n t e r p t2 env

* Var5> t e s t (App (Lam " x " ( Var " x " : + : Var " x " ) ) (Amb (Con1) (Con 2) ) )

" [ 2 , 4 ] "

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 21 / 25

Evaluare cu efecte laterale Sintaxa abstracta

Monada ReaderControl.Monad.Reader

Face accesibila o memorie imutabila (environment)

newtype Reader r a = Reader { runReader : : r −> a }

instance Monad ( Reader r ) wherereturn x = Reader ( \ _ −> x )ma >>= k = Reader $ \ r −>

l e t x = runReader ma rin runReader ( k x ) r

−− obt ine memoriaask : : Reader r rask = Reader ( \ r −> r )

−− modi f i ca l o c a l memorial o c a l : : ( r −> r ) −> Reader r a −> Reader r al o c a l f ma = Reader $ \ r −> runReader ma ( f r )

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 22 / 25

Evaluare cu efecte laterale Sintaxa abstracta

Interpretare în monada ReaderEliminarea argumentului Environment – expresii de baza s, i lookup

type M a = Reader Environment a

showM : : Show a => M a −> StringshowM ma = show $ runReader ma [ ]

i n t e r p : : Term −> M Valuei n t e r p ( Var x ) = lookupM xi n t e r p (Con i ) = return $ Num i

lookupM : : Name −> M ValuelookupM x = do

env <− askcase lookup x env of

Just v −> return vNothing −> return Wrong

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 23 / 25

Evaluare cu efecte laterale Sintaxa abstracta

Interpretare în monada ReaderEliminarea argumentului Environment – operatori binari s, i funct,ii

i n t e r p ( t1 : + : t2 ) = dov1 <− i n t e r p t1v2 <− i n t e r p t2add v1 v2

i n t e r p (App t1 t2 ) = dof <− i n t e r p t1v <− i n t e r p t2apply f v

i n t e r p (Lam x e ) = doenv <− askreturn $ Fun $ \ v −>

l o c a l ( const ( ( x , v ) : env ) ) ( i n t e r p e )

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 24 / 25

Evaluare cu efecte laterale Sintaxa abstracta

Interpretare în monada Reader

type M a = Reader Environment a

showM : : Show a => M a −> StringshowM ma = show $ runReader ma [ ]

i n t e r p : : Term −> M Value

pgm : : Termpgm = App

(Lam " x " ( ( Var " x " ) : + : ( Var " x " ) ) )( ( Con 10) : + : (Con 11) )

* Var6> t e s t pgm" 42 "

Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Monade 25 / 25