Difference between revisions of "Cum este atribuirea in Haskell ?"
Line 1: | Line 1: | ||
Haskell nu foloseste atribuiri in sensul comun al termenului. |
Haskell nu foloseste atribuiri in sensul comun al termenului. |
||
− | Astfel se elimina o sursa importanta de erori, |
+ | '''Astfel se elimina o sursa importanta de erori, (re)atribuirea de valori incorecte variabilelor !''' |
− | Dar daca totusi ordinea calculelor conteaza - cum ati invatat in vechile limbaje - puteti programa in do-notatie, cam asa: |
+ | Dar daca totusi ordinea calculelor conteaza - cum ati invatat in vechile limbaje - puteti programa in do-notatie, cu ceva chiar mai tare decat atribuirile, dar care arata ca niste atribuiri, cam asa: |
<haskell> |
<haskell> |
||
+ | -- Acest exemplu este de corectat |
||
import Data.Char |
import Data.Char |
||
main = do { c <- getChar ; |
main = do { c <- getChar ; |
||
− | b <- ord c ; |
+ | b <- ord c ; |
a <- 1 ; |
a <- 1 ; |
||
− | print (a+b |
+ | print (a+b); |
return 0 } |
return 0 } |
||
+ | </haskell> |
||
+ | Corectura: Intregii 1 si ord c treceti-i prin functia return. Va spun alta data de ce.,. |
||
+ | Programul corect arata asa: |
||
+ | |||
+ | <haskell> |
||
+ | import Data.Char |
||
+ | |||
+ | main = do { c <- getChar ; |
||
+ | b <- return (ord c) ; |
||
+ | a <- return 1 ; |
||
+ | print (a+b); |
||
+ | return 0 } |
||
</haskell> |
</haskell> |
||
+ | Puteti citi cele trei "atribuiri"(de fapt se numesc generatori), astfel: |
||
− | Pagina in dezvoltare .. |
||
+ | |||
+ | c ia valoarea rezultata din actiunea "getChar" |
||
+ | |||
+ | b ia valoarea rezultata din actiunea "return (ord c)" |
||
+ | |||
+ | a ia valoarea rezultata din actiunea "return 1" |
||
+ | |||
+ | Iar daca nu va place sa scrieti return de fiecare data puteti folosi alt nume pentru el, de exemplu val, sau v de la valoare. |
||
+ | |||
+ | <haskell> |
||
+ | import Data.Char |
||
+ | |||
+ | main = do { c <- getChar ; |
||
+ | b <- val (ord c) ; |
||
+ | a <- val 1 ; |
||
+ | print (a+b); |
||
+ | return 0 } |
||
+ | where val = return |
||
+ | </haskell> |
||
+ | |||
+ | ==. Asa ruleaza programul == |
||
+ | |||
+ | <haskell> |
||
+ | |||
+ | Main> main |
||
+ | a |
||
+ | 98 |
||
+ | |||
+ | Main> |
||
+ | |||
+ | </haskell> |
||
+ | |||
+ | |||
+ | ==. Cauza nefunctionarii primului exemplu == |
||
+ | |||
+ | Ca idee, mica incurcatuira este din pricina tipurilor: |
||
+ | |||
+ | <haskell> |
||
+ | ERROR "atribuire.hs":3 - Type error in generator |
||
+ | *** Term : ord c |
||
+ | *** Type : Int |
||
+ | *** Does not match : IO a |
||
+ | |||
+ | Data.Char> :r |
||
+ | ERROR "atribuire.hs":3 - Type error in generator |
||
+ | *** Term : ord c |
||
+ | *** Type : Int |
||
+ | *** Does not match : IO a |
||
+ | |||
+ | Data.Char> :t getChar |
||
+ | getChar :: IO Char |
||
+ | |||
+ | Data.Char> :t ord b |
||
+ | ERROR - Undefined variable "b" |
||
+ | |||
+ | Data.Char> :t ord 'c' |
||
+ | ord 'c' :: Int |
||
+ | |||
+ | Data.Char> :t print 10 |
||
+ | print 10 :: Num a => IO () |
||
+ | |||
+ | </haskell> |
||
+ | |||
+ | La adunarea finala nu pot participa asemenea 'valori' din aceste tipuri diferite. |
||
+ | |||
+ | == Dezavantajul folosirii acestui stil de programare == |
||
+ | Programelke Haskell pur functionale, fara do-uri, compuse numai din functii beneficiaza de o ordine de evaluare dinamic optimizatra, la cererea programului. |
||
+ | Asa ca mai bine scrieti cat mai multe functii fara do-notatie si un mic program main ca mai sus care o foloseste pe do-notatie si le foloseste si pe functiile utilizator. |
Revision as of 20:25, 16 July 2011
Haskell nu foloseste atribuiri in sensul comun al termenului. Astfel se elimina o sursa importanta de erori, (re)atribuirea de valori incorecte variabilelor !
Dar daca totusi ordinea calculelor conteaza - cum ati invatat in vechile limbaje - puteti programa in do-notatie, cu ceva chiar mai tare decat atribuirile, dar care arata ca niste atribuiri, cam asa:
-- Acest exemplu este de corectat
import Data.Char
main = do { c <- getChar ;
b <- ord c ;
a <- 1 ;
print (a+b);
return 0 }
Corectura: Intregii 1 si ord c treceti-i prin functia return. Va spun alta data de ce.,.
Programul corect arata asa:
import Data.Char
main = do { c <- getChar ;
b <- return (ord c) ;
a <- return 1 ;
print (a+b);
return 0 }
Puteti citi cele trei "atribuiri"(de fapt se numesc generatori), astfel:
c ia valoarea rezultata din actiunea "getChar"
b ia valoarea rezultata din actiunea "return (ord c)"
a ia valoarea rezultata din actiunea "return 1"
Iar daca nu va place sa scrieti return de fiecare data puteti folosi alt nume pentru el, de exemplu val, sau v de la valoare.
import Data.Char
main = do { c <- getChar ;
b <- val (ord c) ;
a <- val 1 ;
print (a+b);
return 0 }
where val = return
. Asa ruleaza programul
Main> main
a
98
Main>
. Cauza nefunctionarii primului exemplu
Ca idee, mica incurcatuira este din pricina tipurilor:
ERROR "atribuire.hs":3 - Type error in generator
*** Term : ord c
*** Type : Int
*** Does not match : IO a
Data.Char> :r
ERROR "atribuire.hs":3 - Type error in generator
*** Term : ord c
*** Type : Int
*** Does not match : IO a
Data.Char> :t getChar
getChar :: IO Char
Data.Char> :t ord b
ERROR - Undefined variable "b"
Data.Char> :t ord 'c'
ord 'c' :: Int
Data.Char> :t print 10
print 10 :: Num a => IO ()
La adunarea finala nu pot participa asemenea 'valori' din aceste tipuri diferite.
Dezavantajul folosirii acestui stil de programare
Programelke Haskell pur functionale, fara do-uri, compuse numai din functii beneficiaza de o ordine de evaluare dinamic optimizatra, la cererea programului. Asa ca mai bine scrieti cat mai multe functii fara do-notatie si un mic program main ca mai sus care o foloseste pe do-notatie si le foloseste si pe functiile utilizator.