Personal tools

Cum este atribuirea in Haskell ?

From HaskellWiki

(Difference between revisions)
Jump to: navigation, 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>
  
Pagina in dezvoltare ..
+
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.
 +
 
 +
<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

1 . Asa ruleaza programul

Main> main
a
98
 
Main>


2 . 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.

3 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.