Programare declarativa - Intrare/Iesireold.unibuc.ro/~ileustean/files/10-io-ioana.pdf · Programare...
Transcript of Programare declarativa - Intrare/Iesireold.unibuc.ro/~ileustean/files/10-io-ioana.pdf · Programare...
Programare declarativa1
Intrare/Ies, ire
Traian Florin S, erbanut,aIoana Leus, tean
Departamentul de Informatica, FMI, [email protected]
1bazat pe cursul Informatics 1: Functional Programming de la University of EdinburghTraian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 1 / 41
Despre utilitate s, i sigurant,a
Despre utilitate s, i sigurant,a
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 2 / 41
Despre intent,ie s, i act,iune
Despre intent, ie s, i act, iune
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 3 / 41
Despre intent,ie s, i act,iune
Mind-Body Problem — Comanda vs. Execut, ieCare e legatura dintre intent,ie s, i act,iune, dintre percept,ie s, i înt,elegere?
[1] A purely functional program implements a function;it has no side effect.
[1] Yet the ultimate purpose of running a program is invariably to causesome side effect: a changed file, some new pixels on the screen, amessage sent, ...
[2] Interaction is the mind-body problem of computing.
[1] S. Peyton-Jones, Tackling the Awkward Squad: ... [2] P. Wadler, How to Declare an Imperative
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 4 / 41
Despre intent,ie s, i act,iune
Mind-Body Problem
Ret,eta vs Prajitura
http://www.seas.upenn.edu/~cis194/fall16/lectures/06-io-and-monads.html
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 5 / 41
Despre intent,ie s, i act,iune
Mind-Body Problem
Ret,eta vs Prajitura
http://www.seas.upenn.edu/~cis194/fall16/lectures/06-io-and-monads.html
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 5 / 41
Comenzi în Haskell
Comenzi în Haskell
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 6 / 41
Comenzi în Haskell
Comanda: afis, eaza un caracter!
putChar : : Char −> IO ( )
Exemplu
putChar ’ ! ’
reprezinta o comanda care, daca va fi executata, va afis, a un semn deexclamare.
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 7 / 41
Comenzi în Haskell
Mind-Body Problem - Ret,eta vs Prajiturahttp://www.seas.upenn.edu/~cis194/fall16/lectures/06-io-and-monads.html
c :: Cake r :: Recipe Cake
IO este o ret,eta care produce o valoare de tip a.
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 8 / 41
Comenzi în Haskell
Mind-Body Problem - Ret,eta vs Prajiturahttp://www.seas.upenn.edu/~cis194/fall16/lectures/06-io-and-monads.html
c :: Cake r :: Recipe Cake
IO este o ret,eta care produce o valoare de tip a.
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 8 / 41
Comenzi în Haskell
Comenzi în Haskell
type IO a = RealWorld −> ( a , RealWorld )
S. Peyton-Jones, Tackling the Awkward Squad: ...
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 9 / 41
Comenzi în Haskell
Combina doua comenzi!
( > >) : : IO ( ) −> IO ( ) −> IO ( )putChar : : Char −> IO ( )
Exemplu
putChar ’ ? ’ >> putChar ’ ! ’
rerpezinta o comanda care, daca va fi executata, va afis, a un semn deîntrebare urmat de un semn de exclamare .
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 10 / 41
Comenzi în Haskell Funct,ii folosind comenzi
Afis, eaza un s, ir de caractere
putStr : : String −> IO ( )putStr [ ] = doneputStr ( x : xs ) = putChar x >> putStr xs
Observat,ie:
done : : IO ( )
reprezinta o comanda care, daca va fi executata, nu va face nimic.
Exemplu
putStr " ? ! " == putChar ’ ? ’ >> ( putChar ’ ! ’ >> done )
rerpezinta o comanda care, daca va fi executata, va afis, a un semn deîntrebare urmat de un semn de exclamare.
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 11 / 41
Comenzi în Haskell Funct,ii folosind comenzi
putStr folosind funct, ionale
putStr : : String −> IO ( )putStr = fo ldr ( > >) done . map putChar
Afis, eaza s, i treci pe rândul urmator
putStrLn : : String −> IO ( )putStrLn xs = putStr xs >> putChar ’ \ n ’
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 12 / 41
Comenzi în Haskell Funct,ii folosind comenzi
(IO (), (>>), done) e monoid
m >> done = mdone >> m = m(m >> n ) >> o = m >> ( n >> o )
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 13 / 41
Comenzi în Haskell Funct,ii folosind comenzi
S, i totus, i, când sunt executate comenzile?main
Orice comanda IO a poate fi executata în interpretor, dar
Programele Haskell pot fi compilate
Fis, ierul scrie.hs:
main : : IO ( )main = putStrLn " ? ! "
08− io$ ghc s c r i e . hs[1 of 1] Compil ing Main ( s c r i e . hs , s c r i e . o )L ink ing s c r i e . exe . . .08− io$ . / s c r i e? !
Funct,ia executata este main
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 14 / 41
Comenzi în Haskell Funct,ii folosind comenzi
Când sunt executate comenzile?
Fis, ierul PutStr.hs
module PutSt r where
main : : IO ( )main = putStr " ? ! "
Rularea programului are ca efect executarea comenzii specificate de main:
08− i o$ runghc PutSt r . hs?!08− io$
Observat,ie:runghc ruleaza programul fara a-l compila inainte
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 15 / 41
Validitatea rat,ionamentelor
Validitatea rat, ionamentelor
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 16 / 41
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 in x * x
s, i se evalueaza amândoua la 9
Comenzi
putStr "HA! " >> putStr "HA! "
este echivalenta cu
l e t m = putStr "HA! " in m >> m
si amândoua afis, eaza "HA!HA!".Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 17 / 41
Validitatea rat,ionamentelor
Rat, ionamentele substitutive sunt valabilehttps://en.wikibooks.org/wiki/Haskell/Prologue:_IO,_an_applicative_functor
Referential transparency
orice expresie poate fi înlocuita cu valoare ei
addExclamation : : String −> StringaddExclamation s = s ++ " ! "
main = putStrLn ( addExclamation " He l lo " )Prelude> mainHe l lo !
main = putStrLn ( " He l lo " ++ " ! " )Prelude> mainHe l lo !
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 18 / 41
Validitatea rat,ionamentelor
Rat, ionamentele substitutive sunt valabilehttps://en.wikibooks.org/wiki/Haskell/Prologue:_IO,_an_applicative_functor
addExclamation : : String −> StringaddExclamation s = s ++ " ! "
Observat,ie
Daca getLine ar avea tipul String atunci am putea scrie
main = putStrLn ( addExclamation getLine ) −− cod eronat ! ! !
Nu putem înlocui getLine cu valoarea ei!
Solut,ia: getLine are tipul IO String
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 19 / 41
Validitatea rat,ionamentelor
Rat, ionamentele substitutive sunt valabilehttps://en.wikibooks.org/wiki/Haskell/Prologue:_IO,_an_applicative_functor
addExclamation : : String −> StringaddExclamation s = s ++ " ! "
Observat,ie
Daca getLine ar avea tipul String atunci am putea scrie
main = putStrLn ( addExclamation getLine ) −− cod eronat ! ! !
Nu putem înlocui getLine cu valoarea ei!
Solut,ia: getLine are tipul IO String
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 19 / 41
Validitatea rat,ionamentelor
Rat, ionamentele substitutive sunt valabilehttps://en.wikibooks.org/wiki/Haskell/Prologue:_IO,_an_applicative_functor
addExclamation : : String −> StringaddExclamation s = s ++ " ! "
Observat,ie
Daca getLine ar avea tipul String atunci am putea scrie
main = putStrLn ( addExclamation getLine ) −− cod eronat ! ! !
Nu putem înlocui getLine cu valoarea ei!
Solut,ia: getLine are tipul IO String
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 19 / 41
Comenzi cu valori
Comenzi cu valori
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 20 / 41
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
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 21 / 41
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"
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 22 / 41
Comenzi cu valori
Produ o valoare fara sa faci nimic!Din palarie
return : : 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"
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 23 / 41
Comenzi cu valori
Operatorul de legare
getChar >>= putChar
S. Peyton-Jones, Tackling the Awkward Squad: ...
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 24 / 41
Comenzi cu valori
Combinarea comenzilor cu valoriOperatorul de legare / bind
( > >=) : : IO a −> ( a −> IO b ) −> IO b
Exemplu
getChar >>= \ x −> putChar ( toUpper x )
Daca „s, irul de intrare” cont,ine "abc"atunci comanda de mai sus, atunci când se executa, produce:
ies, irea "A"s, irul ramas de intrare "bc"
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 25 / 41
Comenzi cu valori
Operatorul de legare / bindMai multe detalii
( > >=) : : IO a −> ( a −> IO b ) −> IO b
Daca fiind o comanda care produce o valoare de tip am :: IO a
Data fiind o funct,ie care pentru o valoare de tip a se evalueaza la ocomanda de tip bk :: a −> IO b
Atuncim >>= k :: IO beste comanda care, daca se va executa:
Mai întâi efectueaza m, obt, inând valoarea x de tip aApoi efectueaza comanda k x obt, inând o valoare y de tip bProduce y ca rezultat al comenzii
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 26 / 41
Comenzi cu valori
Cites, te o linie!
getLine : : IO StringgetLine = getChar >>= \ x −>
i f x == ’ \ n ’ thenreturn [ ]
elsegetLine >>= \ xs −>return ( x : xs )
Exemplu
Dat fiind s, irul de intrare "abc\ndef", getLine produce s, irul "abc" s, i s, irulramas de intrare e "def"
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 27 / 41
Comenzi cu valori
Comenzile sunt cazuri speciale de comenzi cu valori
done e caz special de return
done : : IO ( )done = return ( )
>> e caz special de >>=
( > >) : : IO ( ) −> IO ( ) −> IO ( )m >> n = m >>= \ ( ) −> n
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 28 / 41
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
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 29 / 41
Comenzi cu valori
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 30 / 41
Comenzi cu valori
De la intrare la ies, ire
echo : : IO ( )echo = getLine >>= \ l i n e −>
i f l i n e == " " thenreturn ( )
elseputStrLn (map toUpper l i n e ) >>echo
main : : IO ( )main = echo
Test
$ runghc Echo . hsOne l i n eONE LINEAnd , another l i n e !AND, ANOTHER LINE !
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 31 / 41
Comenzi cu valori
De la intrare la ies, ire
echo : : IO ( )echo = getLine >>= \ l i n e −>
i f l i n e == " " thenreturn ( )
elseputStrLn (map toUpper l i n e ) >>echo
main : : IO ( )main = echo
Test
$ runghc Echo . hsOne l i n eONE LINEAnd , another l i n e !AND, ANOTHER LINE !
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 31 / 41
Notat,ia do
Notat, ia do
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 32 / 41
Notat,ia do
Citirea unei linii în notat, ie „do”getLine : : IO StringgetLine = getChar >>= \ x −>
i f x == ’ \ n ’ thenreturn [ ]
elsegetLine >>= \ xs −>return ( x : xs )
Echivalent cu:getLine : : IO StringgetLine = do {
x <− getChar ;i f x == ’ \ n ’ then
return [ ]else do {
xs <− getLine ;return ( x : xs )
}}
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 33 / 41
Notat,ia do
Echo în notat, ia „do”echo : : IO ( )echo = getLine >>= \ l i n e −>
i f l i n e == " " thenreturn ( )
elseputStrLn (map toUpper l i n e ) >>echo
Echivalent cuecho : : 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
}}
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 34 / 41
Notat,ia do
Notat, ia „do” în general
Fiecare linie x <− e; ... devine e >>= \x −> ...Fiecare linie e; ... devine e >> ...
De exempludo { x1 <− e1 ;
x2 <− e2 ;e3 ;x4 <− e4 ;e5 ;e6 }
e echivalent cue1 >>= \ x1 −>e2 >>= \ x2 −>e3 >>e4 >>= \ x4 −>e5 >>e6
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 35 / 41
Citire/Scriere din fis, iere
Citire/Scriere din fis, iere
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 36 / 41
Citire/Scriere din fis, iere
Citirea/ Scrierea din fis, iereOperat,ii de baza
type FilePath = String
readFi le : : FilePath −> IO String
wr i teF i le : : FilePath −> String −> IO ( )
appendFile : : FilePath −> String −> IO ( )
echof = dos <− readFi le " f i s 1 . t x t "putStrLn swr i teF i le " f i s 2 . t x t " s
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 37 / 41
Citire/Scriere din fis, iere
Citirea/ Scrierea din fis, iereOperat,ii de baza
import Data . Char ( toUpper )
main = dos <− readFi le " Inpu t . t x t "putStrLn $ " I n t r a r e \ n " ++ s
l e t sp re l = map toUpper s −− p re luc ra re date c i t i t e
putStrLn $ " I e s i r e \ n " ++ sp re lwr i teF i le " Output . t x t " sp re l −− appendFi le
Observat,ii:
readFile cites, te (lenes, ) cont,inutul fis, ierului
writeFile s, i appendFile creaza fis, ierele daca acestea nu exista.
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 38 / 41
Citire/Scriere din fis, iere
Citirea/ Scrierea numerelor din fis, iereOperat,ii de baza
l i s t N o s t r = concat $ map words $ l ines s t r
readNumbers f i l e 1 f i l e 2 = dos t r <− readFi le f i l e 1putStrLn $ " I n t r a r e \ n "l e t numbers = (map read $ l i s t N o s ) : : [ I n t ]pr in t numberswr i teF i le f i l e 2 (show numbers )
> readNumbers " f i o . t x t " " f o u t . t x t "
Observat,ii:
print este putStrLn . show
putem scrie in fisier numai date care sunt instanta a clasei Show
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 39 / 41
Citire/Scriere din fis, iere
??????
https://crypto.stanford.edu/~blynn/haskell/
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 40 / 41
Citire/Scriere din fis, iere
Tema pentru vacant,a
Simon Peyton Jones — Haskell is Useless
http://www.youtube.com/watch?v=iSmkqocn0oQ
Atent,ie! Înregistrarea este din 2011.
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 41 / 41
Citire/Scriere din fis, iere
Tema pentru vacant,a
Simon Peyton Jones — Haskell is Useless
http://www.youtube.com/watch?v=iSmkqocn0oQ
Atent,ie! Înregistrarea este din 2011.
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 41 / 41
Citire/Scriere din fis, iere
Tema pentru vacant,a
Simon Peyton Jones — Haskell is Useless
http://www.youtube.com/watch?v=iSmkqocn0oQ
Atent,ie! Înregistrarea este din 2011.
Traian Florin S, erbanut,a Ioana Leus, tean (UB) PD—Intrare/Ies, ire 41 / 41