Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pp:21:laboratoare:racket:functionale [2021/03/15 16:16]
bot.pp created
pp:21:laboratoare:racket:functionale [2021/03/25 15:31] (current)
bot.pp
Line 1: Line 1:
 ====== Racket: Funcții ca valori. Funcționale ====== ====== Racket: Funcții ca valori. Funcționale ======
  
-  * Data publicării:​ 15.03.2020+  * Data publicării:​ 15.03.2021
   * Data ultimei modificări:​ 15.03.2021   * Data ultimei modificări:​ 15.03.2021
  
Line 18: Line 18:
  
   * legate la un identificator:​ ''​%%(define par? even?​)%%''​   * legate la un identificator:​ ''​%%(define par? even?​)%%''​
-  * stocate într-o structură de date: ''​%%(list ​\\> odd? even?​)%%''​+  * stocate într-o structură de date: ''​%%(list < > odd? even?​)%%''​
   * pasate ca argumente într-un apel de funcție: ''​%%(list?​ even?​)%%''​   * pasate ca argumente într-un apel de funcție: ''​%%(list?​ even?​)%%''​
   * returnate ca rezultat al unui apel de funcție: funcții curry din paragraful următor   * returnate ca rezultat al unui apel de funcție: funcții curry din paragraful următor
Line 26: Line 26:
 O funcție care își primește toți parametrii deodată se numește funcție **uncurry**. Până acum ați folosit doar funcții uncurry. O funcție care își primește toți parametrii deodată se numește funcție **uncurry**. Până acum ați folosit doar funcții uncurry.
  
-<​code>​+<​code ​lisp>
 (define add-uncurry (define add-uncurry
   (lambda (x y)   (lambda (x y)
Line 34: Line 34:
 O funcție care returnează o nouă funcție atunci când este aplicată pe mai puține argumente decât îi sunt necesare se numește funcție **curry**. O funcție care returnează o nouă funcție atunci când este aplicată pe mai puține argumente decât îi sunt necesare se numește funcție **curry**.
  
-<​code>​+<​code ​lisp>
 (define add-curry (define add-curry
   (lambda (x)   (lambda (x)
Line 45: Line 45:
 Funcțiile curry facilitează reutilizarea de cod, permițând obținerea unor funcții particulare din funcții mai generale: Funcțiile curry facilitează reutilizarea de cod, permițând obținerea unor funcții particulare din funcții mai generale:
  
-<​code>​+<​code ​lisp>
 (define inc-curry (add-curry 1)) (define inc-curry (add-curry 1))
  
Line 53: Line 53:
 În secvența de cod de mai jos sunt implementate două funcții. Prima funcție obține pătratele elementelor unei liste, iar a doua funcție obține cuburile elementelor listei. În secvența de cod de mai jos sunt implementate două funcții. Prima funcție obține pătratele elementelor unei liste, iar a doua funcție obține cuburile elementelor listei.
  
-<​code>​+<​code ​lisp>
 (define (sq x) (\* x x)) (define (sq x) (\* x x))
 (define (cub x) (\* x x x)) (define (cub x) (\* x x x))
Line 73: Line 73:
 După cum se poate observa, ambele funcții folosesc același pattern: După cum se poate observa, ambele funcții folosesc același pattern:
  
-<​code>​+<​code ​lisp>
 (define (?nume L) (define (?nume L)
   (if (null?​ L)   (if (null?​ L)
Line 84: Line 84:
 Prin urmare, pentru a nu scrie de două ori același cod putem defini o altă funcție mai generală: Prin urmare, pentru a nu scrie de două ori același cod putem defini o altă funcție mai generală:
  
-<​code>​+<​code ​lisp>
 (define (general-func f L) (define (general-func f L)
   (if (null?​ L)   (if (null?​ L)
Line 93: Line 93:
 Această funcție poate fi apoi folosită pentru a implementa sq-every și cub-every: Această funcție poate fi apoi folosită pentru a implementa sq-every și cub-every:
  
-<​code>​+<​code ​lisp>
 (define (sq-every L) (general-func sq L)) (define (sq-every L) (general-func sq L))
 (define (cub-every L) (general-func cub L)) (define (cub-every L) (general-func cub L))
Line 102: Line 102:
 Deoarece funcțiile sq si cub sunt folosite o singură dată, acestea pot fi scrise in-place ca funcții anonime: Deoarece funcțiile sq si cub sunt folosite o singură dată, acestea pot fi scrise in-place ca funcții anonime:
  
-<​code>​+<​code ​lisp>
 (define (sq-every-in-place L) (general-func (lambda (x) (\* x x)) L)) (define (sq-every-in-place L) (general-func (lambda (x) (\* x x)) L))
 (define (cub-every-in-place L) (general-func (lambda (x) (\* x x x)) L)) (define (cub-every-in-place L) (general-func (lambda (x) (\* x x x)) L))
Line 109: Line 109:
 Dacă dorim să scriem încă o funcție care să adune 2 la fiecare element al unei liste de numere, tot ce trebuie să facem este să folosim funcția general-func:​ Dacă dorim să scriem încă o funcție care să adune 2 la fiecare element al unei liste de numere, tot ce trebuie să facem este să folosim funcția general-func:​
  
-<​code>​+<​code ​lisp>
 (define (+2-every L) (general-func (lambda (x) (+ 2 x)) L)) (define (+2-every L) (general-func (lambda (x) (+ 2 x)) L))
  
Line 115: Line 115:
 Însă codul de mai sus mai poate fi simplificat. Nu este nevoie să definim o nouă funcție pentru adunarea cu 2 a unui număr, ci ne putem folosi de funcția de adunare deja definită, pe care o aplicăm pe un singur parametru: Însă codul de mai sus mai poate fi simplificat. Nu este nevoie să definim o nouă funcție pentru adunarea cu 2 a unui număr, ci ne putem folosi de funcția de adunare deja definită, pe care o aplicăm pe un singur parametru:
  
-<​code>​+<​code ​lisp>
 (define (+2-every L) (general-func (add-curry 2) L)) (define (+2-every L) (general-func (add-curry 2) L))
  
Line 129: Line 129:
   * ''​%%map%%'':​ returnează lista rezultatelor aplicării unei funcții f asupra fiecărui element dintr-o listă. [Obs: ''​%%map%%''​ poate primi n liste și atunci f are n parametrii, fiecare din câte o listă. Listele trebuie să aibă aceeași lungime]   * ''​%%map%%'':​ returnează lista rezultatelor aplicării unei funcții f asupra fiecărui element dintr-o listă. [Obs: ''​%%map%%''​ poate primi n liste și atunci f are n parametrii, fiecare din câte o listă. Listele trebuie să aibă aceeași lungime]
  
-<​code>​+<​code ​lisp>
 (map f L) (map f L)
  
Line 135: Line 135:
 Mai jos se pot observa câteva exemple folosind map: Mai jos se pot observa câteva exemple folosind map:
  
-<​code>​+<​code ​lisp>
 (map add1 '(1 4 7 10)) ; întoarce '(2 5 8 11) (map add1 '(1 4 7 10)) ; întoarce '(2 5 8 11)
 (map sqr '(1 2 3 4)) ; întoarce '(1 4 9 16) (map sqr '(1 2 3 4)) ; întoarce '(1 4 9 16)
Line 145: Line 145:
   * ''​%%filter%%'':​ returnează lista elementelor dintr-o listă care satisfac un predicat p.   * ''​%%filter%%'':​ returnează lista elementelor dintr-o listă care satisfac un predicat p.
  
-<​code>​+<​code ​lisp>
 (filter p L) (filter p L)
  
Line 151: Line 151:
 Mai jos se pot observa câteva exemple folosind filter: Mai jos se pot observa câteva exemple folosind filter:
  
-<​code>​+<​code ​lisp>
 (filter even? '(1 3 4 7 8)) ; întoarce '(4 8) (filter even? '(1 3 4 7 8)) ; întoarce '(4 8)
 (filter positive? '(1 -2 3 4 -5)) ; întoarce '(1 3 4) (filter positive? '(1 -2 3 4 -5)) ; întoarce '(1 3 4)
Line 159: Line 159:
   * ''​%%foldl%%''​ (//fold left//): returnează rezultatul aplicării funcției f pe rând asupra unui element din listă și a unui acumulator. Ordinea folosirii elementelor din listă este de la stânga la dreapta. [Obs: ''​%%foldl%%''​ poate primi n liste și atunci f are (+ n 1) parametrii, dintre care ultimul este acumulatorul. Listele trebuie să aibă același număr de elemente]   * ''​%%foldl%%''​ (//fold left//): returnează rezultatul aplicării funcției f pe rând asupra unui element din listă și a unui acumulator. Ordinea folosirii elementelor din listă este de la stânga la dreapta. [Obs: ''​%%foldl%%''​ poate primi n liste și atunci f are (+ n 1) parametrii, dintre care ultimul este acumulatorul. Listele trebuie să aibă același număr de elemente]
  
-<​code>​+<​code ​lisp>
 (foldl f init L) (foldl f init L)
  
Line 165: Line 165:
 Mai jos se pot observa câteva exemple folosind foldl: Mai jos se pot observa câteva exemple folosind foldl:
  
-<​code>​+<​code ​lisp>
 (foldl cons null '(1 2 3 4)) ; întoarce '(4 3 2 1) (foldl cons null '(1 2 3 4)) ; întoarce '(4 3 2 1)
 (foldl (lambda (x y result) (* result (+ x y))) 1 '(4 7 2) '(-6 3 -1)) ; întoarce -20 (foldl (lambda (x y result) (* result (+ x y))) 1 '(4 7 2) '(-6 3 -1)) ; întoarce -20
Line 172: Line 172:
   * ''​%%foldr%%''​ (//fold right//): singurele diferențe între foldl și foldr este că foldr ia elementele de la dreapta spre stânga și că are nevoie de un spațiu proporțional cu lungimea listei.   * ''​%%foldr%%''​ (//fold right//): singurele diferențe între foldl și foldr este că foldr ia elementele de la dreapta spre stânga și că are nevoie de un spațiu proporțional cu lungimea listei.
  
-<​code>​+<​code ​lisp>
 (foldr f init L) (foldr f init L)
  
Line 178: Line 178:
 Mai jos se pot observa câteva exemple folosind foldr: Mai jos se pot observa câteva exemple folosind foldr:
  
-<​code>​+<​code ​lisp>
 (foldr cons null '(1 2 3 4)) ; întoarce '(1 2 3 4) (foldr cons null '(1 2 3 4)) ; întoarce '(1 2 3 4)
 (foldr (lambda (x acc) (cons (* x 2) acc)) null '(1 2 3 4)) ; întoarce '(2 4 6 8) (foldr (lambda (x acc) (cons (* x 2) acc)) null '(1 2 3 4)) ; întoarce '(2 4 6 8)
Line 185: Line 185:
   * ''​%%apply%%'':​ returnează rezultatul aplicării unei funcții f cu argumente elementele din lista L   * ''​%%apply%%'':​ returnează rezultatul aplicării unei funcții f cu argumente elementele din lista L
  
-<​code>​+<​code ​lisp>
 (apply f L) (apply f L)
  
Line 191: Line 191:
 Mai jos se pot observa câteva exemple folosind apply: Mai jos se pot observa câteva exemple folosind apply:
  
-<​code>​+<​code ​lisp>
 (apply + '(1 2 3 4)) ; întoarce 10 (apply + '(1 2 3 4)) ; întoarce 10
 (apply * 1 2 '(3 4)) ; întoarce 24 (apply * 1 2 '(3 4)) ; întoarce 24
Line 205: Line 205:
 De multe ori, funcționalele ''​%%map%%''​ și ''​%%apply%%''​ sunt încurcate. Pentru a înțelege mai bine diferența dintre acestea, urmăriți rezultatele exemplelor de mai jos. De multe ori, funcționalele ''​%%map%%''​ și ''​%%apply%%''​ sunt încurcate. Pentru a înțelege mai bine diferența dintre acestea, urmăriți rezultatele exemplelor de mai jos.
  
-<​code>​+<​code ​lisp>
 (map list '(1 2 3)) ; întoarce'​((1) (2) (3)) (map list '(1 2 3)) ; întoarce'​((1) (2) (3))
 (apply list '(1 2 3)) ; întoarce '(1 2 3) (apply list '(1 2 3)) ; întoarce '(1 2 3)
Line 214: Line 214:
 O altă greșeală întâlnită frecvent apare atunci când funcțiile primite ca argument de către funcționale sunt plasate între paranteze. O altă greșeală întâlnită frecvent apare atunci când funcțiile primite ca argument de către funcționale sunt plasate între paranteze.
  
-<​code>​+<​code ​lisp>
 (filter (odd?) '(1 2 3 4 5)) ; odd?: arity mismatch; (GREȘIT) (filter (odd?) '(1 2 3 4 5)) ; odd?: arity mismatch; (GREȘIT)
 (filter odd? '(1 2 3 4 5)) ; întoarce '(1 3 5) (CORECT) (filter odd? '(1 2 3 4 5)) ; întoarce '(1 3 5) (CORECT)
pp/21/laboratoare/racket/functionale.1615817814.txt.gz · Last modified: 2021/03/15 16:16 by bot.pp
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0