Programare declarativa - Monade Standardold.unibuc.ro/~ileustean/files/13-monade-standard.pdf ·...
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]
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