Difference between revisions of "Cum este atribuirea in Haskell ?"

From HaskellWiki
Jump to navigation Jump to search
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, REatribuirea de valori incorecte variabilelor.
+
'''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+c);
+
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.