Sunteți pe pagina 1din 33

Programare declarativa 1

Intrare/Ies, ire

, a
Traian Florin S, erbanut
FMI, UNIBUC
Departamentul de Informatica,
traian.serbanuta@fmi.unibuc.ro

20 noiembrie 2015

bazat pe cursul Informatics 1: Functional Programming de la University of Edinburgh

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

1 / 32

Despre utilitate s, i sigurant,a

Despre utilitate s, i sigurant, a

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

2 / 32

Despre utilitate s, i sigurant,a

Simon Peyton Jones Haskell is Useless


http://www.youtube.com/watch?v=iSmkqocn0oQ

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

3 / 32

Despre intent,ie s, i act,iune

Despre intent, ie s, i act, iune

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

4 / 32

Despre intent,ie s, i act,iune

Mind-Body Problem Comanda vs. Execut, ie

Care e legatura
dintre intent, ie s, i act, iune, dintre percept, ie s, i nt, elegere?

Idealism (Platon)
Dualism (Descartes)
Fizicalism (materialism)
Neutral Monism

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

5 / 32

Comenzi n Haskell

Comenzi n Haskell

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

6 / 32

Comenzi n Haskell

Afis, eaza un caracter!

putChar : : Char > IO ( )

Exemplu
putChar

va afis, a un semn de
rerpezinta o comanda care, daca va fi executata,
exclamare.

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

7 / 32

Comenzi n Haskell

Combina doua comenzi!

( > >) : : IO ( ) > IO ( ) > IO ( )


putChar : : Char > IO ( )

Exemplu
putChar ? >> putChar

va afis, a un semn de
rerpezinta o comanda care, daca va fi executata,
ntrebare urmat de un semn de exclamare .

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

8 / 32

Comenzi n Haskell

Stai locului! (nu face nimic!)

done : : IO ( )

nu va face nimic.
done rerpezinta o comanda care, daca va fi executata,

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

9 / 32

Comenzi n Haskell

Funct,ii folosind comenzi

Afis, eaza un s, ir de caractere

putStr : : S t r i n g > IO ( )
putStr [ ]
= done
putStr ( x : xs ) = putChar x >> putStr xs

Exemplu
putStr " ? ! " == putChar ? >> ( putChar

! >> done )

va afis, a un semn de
rerpezinta o comanda care, daca va fi executata,
ntrebare urmat de un semn de exclamare.

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

10 / 32

Comenzi n Haskell

Funct,ii folosind comenzi

putStr folosind funct, ionale

putStr
putStr

: : S t r i n g > IO ( )
= f o l d r ( > >) done . map putChar

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

11 / 32

Comenzi n Haskell

Funct,ii folosind comenzi

(IO (), (>>), done) e monoid

m >> done
done >> m
(m >> n ) >> o

,a (UNIBUC)
Traian Florin S, erbanut

=
=
=

m
m
m >> ( n >> o )

PDIntrare/Ies, ire

20 noiembrie 2015

12 / 32

Comenzi n Haskell

Funct,ii folosind comenzi

S, i totus, i, cnd sunt executate comenzile?


main

Fis, ierul PutStr.hs


module P u t S t r where
main : : IO ( )
main = putStr " ? ! "

Rularea programului are ca efect executarea comenzii specificate de main:


08 i o $ runghc P u t S t r . hs
?!08 i o $

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

13 / 32

Comenzi n Haskell

Funct,ii folosind comenzi

Afis, eaza s, i treci pe rndul urmator


putStrLn : : S t r i n g > IO ( )
putStrLn xs = putStr xs >> putChar \ n

Fis, ierul ScrieLinie.hs


module S c r i e L i n i e where
s t a r t : : IO ( )
s t a r t = putStrLn " ? ! "

Rulare cu compilare:
08 i o $ ghc S c r i e L i n i e . hs main i s S c r i e L i n i e . s t a r t o s c r i e
[ 1 of 1 ] Compiling S c r i e L i n i e ( S c r i e L i n i e . hs , S c r i e L i n i e . o )
Linking scrie . . .
08 i o $ . / s c r i e
?!
08 i o $
,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

14 / 32

Validitatea rat,ionamentelor

Validitatea rat, ionamentelor

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

15 / 32

Validitatea rat,ionamentelor

Rat, ionamentele substitutive s, i pierd valabilitatea


n limbaje cu efecte laterale

Program 1
int main() { cout << "HA!"; cout << "HA!"; }

Program 2
void dup(auto& x) { x ; x; }
int main() { dup(cout << "HA!"); }

Program 3
void dup(auto x) { x() ; x (); }
int main() { dup( []() { cout << "HA!"; } ); }

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

16 / 32

Validitatea rat,ionamentelor

Rat, ionamentele substitutive sunt valabile


n Haskell

Expresii
(1+2) * (1+2)

este echivalenta cu expresia


l e t x = 1+2 i n x * x

s, i se evalueaza amndoua la 9
Comenzi
putStr "HA! " >> putStr "HA! "

este echivalenta cu
l e t m = putStr "HA! " i n m >> m

si amndoua afis, eaza "HA!HA!".


,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

17 / 32

Comenzi cu valori

Comenzi cu valori

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

18 / 32

Comenzi cu valori

Comenzi cu valori

IO () corespunde comenzilor care nu produc rezultate


() este tipul unitate care cont, ine doar valoarea ()

n general, IO a corespunde comenzilor care produc rezultate de tip a.


IO Char corespunde comenzilor care produc rezultate de tip Char

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

19 / 32

Comenzi cu valori

Cites, te un caracter!

getChar : : IO Char

Daca s, irul de intrare cont, ine "abc"


atunci getChar produce:
a

s, irul ramas
de intrare "bc"

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

20 / 32

Comenzi cu valori

sa faci nimic!
Produ o valoare fara
arie

Din pal

r e t u r n : : a > IO a

Asemanatoar
cu done, nu face nimic, dar produce o valoare.
Exemplu
return " "

Daca s, irul de intrare cont, ine "abc"


atunci return "" produce:
valoarea ""
s, irul (neschimbat) de intrare "abc"

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

21 / 32

Comenzi cu valori

Combinarea comenzilor cu valori


Operatorul de legare / bind

( > >=) : : IO a > ( a > IO b ) > IO b

Exemplu
getChar >>= \ x > putChar ( toUpper x )

Daca s, irul de intrare cont, ine "abc"


produce:
atunci comanda de mai sus, atunci cnd se executa,
ies, irea "A"

s, irul ramas
de intrare "bc"

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

22 / 32

Comenzi cu valori

Operatorul de legare / bind


Mai multe detalii

( > >=) : : IO a > ( a > IO b ) > IO b

Daca fiind o comanda care produce o valoare de tip a


m :: IO a
Data fiind o funct, ie care pentru o valoare de tip a se evalueaza la o
comanda de tip b
k :: a > IO b
Atunci
m >>= k :: IO b
este comanda care, daca se va executa:
Mai nti efectueaza m, obt, innd valoarea x de tip a
Apoi efectueaza comanda k x obt, innd o valoare y de tip b
Produce y ca rezultat al comenzii
,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

23 / 32

Comenzi cu valori

Cites, te o linie!

getLine : : IO S t r i n g
getLine = getChar >>= \ x >
i f x == \ n then
return [ ]
else
getLine >>= \ xs >
r e t u r n ( x : xs )

Exemplu
Dat fiind s, irul de intrare "abc\ndef", getLine produce s, irul "abc" s, i s, irul

ramas
de intrare e "def"

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

24 / 32

Comenzi cu valori

Comenzile sunt cazuri speciale de comenzi cu valori

done e caz special de return


done
done

: : IO ( )
= return ( )

>> e caz special de >>=


( > >)
m >> n

: : IO ( ) > IO ( ) > IO ( )
= m >>= \ ( ) > n

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

25 / 32

Comenzi cu valori

Operatorul de legare e similar cu let


Operatorul let
l e t x = m in n

let ca aplicat, ie de funct, ii


( \ x > n ) m

Operatorul de legare
m >>= \ x > n

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

26 / 32

Comenzi cu valori

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

27 / 32

Comenzi cu valori

De la intrare la ies, ire


echo : : IO ( )
echo = getLine >>= \ l i n e >
i f l i n e == " " then
return ( )
else
putStrLn (map toUpper l i n e ) >>
echo
main : : IO ( )
main = echo

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

28 / 32

Comenzi cu valori

De la intrare la ies, ire


echo : : IO ( )
echo = getLine >>= \ l i n e >
i f l i n e == " " then
return ( )
else
putStrLn (map toUpper l i n e ) >>
echo
main : : IO ( )
main = echo

Test
$ runghc Echo . hs
One l i n e
ONE LINE
And , a n o t h e r l i n e !
AND, ANOTHER LINE !
,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

28 / 32

Notat,ia do

Notat, ia do

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

29 / 32

Notat,ia do

Citirea unei linii n notat, ie do


getLine : : IO S t r i n g
getLine = getChar >>= \ x >
i f x == \ n then
return [ ]
else
getLine >>= \ xs >
r e t u r n ( x : xs )

Echivalent cu:
getLine : : IO S t r i n g
getLine = do {
x < getChar ;
i f x == \ n then
return [ ]
else do {
xs < getLine ;
r e t u r n ( x : xs )
}
}
,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

30 / 32

Notat,ia do

Echo n notat, ia do
echo : : IO ( )
echo = getLine >>= \ l i n e >
i f l i n e == " " then
return ( )
else
putStrLn (map toUpper l i n e ) >>
echo

Echivalent cu
echo : : IO ( )
echo = do {
l i n e < getLine ;
i f l i n e == " " then
return ( )
else do {
putStrLn (map toUpper l i n e ) ;
echo
}
}
,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

31 / 32

Notat,ia do

Notat, ia do n general
Fiecare linie x < e; ... devine e >>= \x > ...
Fiecare linie e; ... devine e >> ...
De exemplu
do { x1 < e1 ;
x2 < e2 ;
e3 ;
x4 < e4 ;
e5 ;
e6 }

e echivalent cu
e1
e2
e3
e4
e5
e6

>>= \ x1 >
>>= \ x2 >
>>
>>= \ x4 >
>>

,a (UNIBUC)
Traian Florin S, erbanut

PDIntrare/Ies, ire

20 noiembrie 2015

32 / 32