This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
laboratoare:09-intarzierea-evaluarii-inchideri-nulare [2015/04/20 20:05] matei.popovici [Evaluare leneșă] |
laboratoare:09-intarzierea-evaluarii-inchideri-nulare [2016/04/12 12:19] (current) mihai.dumitru2201 |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ===== Laborator 9 - Întârzierea evaluării ===== | + | ===== Întârzierea evaluării ===== |
Line 7: | Line 7: | ||
* **promisiuni** | * **promisiuni** | ||
- | ====Evaluare aplicativă vs. evaluare leneșă==== | + | ====Evaluare aplicativă vs. evaluare normala==== |
Fie urmatoarea expresie, scrisă într-o varianta relaxata a Calculului Lambda (in care valori numerice si operatii pe acestea sunt permise, iar functiile sunt in forma uncurry): | Fie urmatoarea expresie, scrisă într-o varianta relaxata a Calculului Lambda (in care valori numerice si operatii pe acestea sunt permise, iar functiile sunt in forma uncurry): | ||
Line 31: | Line 31: | ||
====Evaluare normală==== | ====Evaluare normală==== | ||
- | Spre deosebire de evaluarea aplicativă, evaluarea leneșă va întarzia evaluarea unei expresii, până când aceasta este folosită efectiv. Exemplu: | + | Spre deosebire de evaluarea aplicativă, evaluarea normală va întarzia evaluarea unei expresii, până când aceasta este folosită efectiv. Exemplu: |
<code>(λx.λy.(x + y) 1 (λz.(z + 2) 3)) | <code>(λx.λy.(x + y) 1 (λz.(z + 2) 3)) | ||
Line 62: | Line 62: | ||
====Aplicatii:==== | ====Aplicatii:==== | ||
- | 1. Definiți un stream de numere 1 'ones_stream' folosind evaluarea lenesa din scheme care apeland | + | === Siruri in Scheme === |
- | * ''(ones_stream)'' => ''(1 . #procedure)'' unde dacă vom apela ''(#procedure)'', vom obtine: | + | |
- | * ''(1 . #procedure)'' din nou. | + | |
- | + | - Definiți un stream de numere 1 'ones_stream' folosind evaluarea normala din Scheme | |
- | 2. Creati o funcție take care să funcționeze ca cea din haskell (take 5 [1,1..] va intoarce [1,1,1,1,1] in haskell) | + | - Creati o funcție take care să funcționeze ca cea din Haskell (take 5 [1,1..] va intoarce [1,1,1,1,1] in haskell) |
* ''(take 5 ones_stream)'' => ''(1 1 1 1 1)'' | * ''(take 5 ones_stream)'' => ''(1 1 1 1 1)'' | ||
- | + | - Creati un stream de numere naturale care va fi reprezentat astfel: | |
- | + | ||
- | 3. Creati un stream de numere naturale care va fi reprezentat astfel: | + | |
* ''(0 . #procedure)'', unde dacă vom apela procedure vom obtine | * ''(0 . #procedure)'', unde dacă vom apela procedure vom obtine | ||
* ''(1 . #procedure)'', unde dacă iar apelam procedure-ul nou obtinut, obtinem | * ''(1 . #procedure)'', unde dacă iar apelam procedure-ul nou obtinut, obtinem | ||
Line 77: | Line 73: | ||
* HINT: veți avea nevoie de o funcție ajutătoare | * HINT: veți avea nevoie de o funcție ajutătoare | ||
* Testați: ''(take 5 naturals_stream)'' => ''(0 1 2 3 4)'' | * Testați: ''(take 5 naturals_stream)'' => ''(0 1 2 3 4)'' | ||
- | + | - Definiți o funcție care sa adune două stream-uri: | |
- | + | ||
- | 4. Definiți o funcție care sa adune două stream-uri: | + | |
* ''(take 5 (sum_stream naturals_stream ones_stream))'' => ''(1 2 3 4 5)'' | * ''(take 5 (sum_stream naturals_stream ones_stream))'' => ''(1 2 3 4 5)'' | ||
- | + | * pentru acest task, implementati o functie ''zipWith'' care sa opereze pe stream-uri | |
- | + | - Creați un stream de numere pare: | |
- | 5. Creați un stream de numere pare: | + | |
* Testati: ''(take 5 even_stream)'' => ''(0 2 4 6 8)'' | * Testati: ''(take 5 even_stream)'' => ''(0 2 4 6 8)'' | ||
- | + | * pentru acest task, implementati o functie ''map'' care sa opereze pe stream-uri | |
- | + | - Creați șirul numerelor Fibonacci: | |
- | 6. Creați șirul numerelor fibonacci: | + | |
* ''(take 5 fibo_stream)'' => ''(0 1 1 2 3)'' | * ''(take 5 fibo_stream)'' => ''(0 1 1 2 3)'' | ||
* Observam ca fibonacci e definit prin adunarea stream-urilor anterioare. | * Observam ca fibonacci e definit prin adunarea stream-urilor anterioare. | ||
Line 96: | Line 88: | ||
Fibo = t0 t1 t2 t3 t4 t5 ... tk ... </code> | Fibo = t0 t1 t2 t3 t4 t5 ... tk ... </code> | ||
* Observam că, adunand elemente din sirurile (fluxurile) Fibo și (tail Fibo), obtinem sirul t2 t3 t4 .. tk . Dacă adăugam primele două elemente, t0 si t1 la inceput, obținem exact Fibo. | * Observam că, adunand elemente din sirurile (fluxurile) Fibo și (tail Fibo), obtinem sirul t2 t3 t4 .. tk . Dacă adăugam primele două elemente, t0 si t1 la inceput, obținem exact Fibo. | ||
+ | |||
+ | === Siruri in Haskell === | ||
+ | - Construiti sirul numerelor naturale | ||
+ | - Construiti sirul numerelor pare | ||
+ | - Construiti sirul numerelor lui Fibonacci | ||
+ | |||
+ | === Aproximatii (in Haskell) === | ||
+ | - definiti o functie ''build :: (a -> a) -> a -> [a]'' care primeste o functie 'generator' (pe care o numim ''g'' in continuare), o valoare initiala (''a0''), si generaza lista: ''[a0, g a0, g (g a0), g (g (g a0)), ... '' | ||
+ | - definiti o functie ''select'' care primeste o toleranta ''e'', o lista, si intoarce valoarea ''an'' care satisface proprietatea: ''|an - a{n+1}| < e'' | ||
+ | - Aproximatie pentru ''sqrt(k)'': | ||
+ | * Scrieti o functie care calculeaza ''sqrt(k)'' cu toleranta ''0.01'', exploatand faptul ca sirul: ''an = 1/2(a{n-1} + k/a{n-1})'' converge catre ''sqrt(k)'' cand ''n'' tine de la infinit. | ||
+ | - Aproximatie pentru derivata unei functii ''f'' intr-un punct ''a'' | ||
+ | * Scrieti o functie care genereaza lista: ''[h0, h0/2, h0/4, h0/8, ...]'' | ||
+ | * Scrieti o functie care calculeaza lista aproximarilor lui ''f'(a)'', calculate astfel: ''f'(a)=f(a+h)-f(a)/h'' | ||
+ | * Scrieti o functie care calculeaza derivata in ''a'' a unei functii ''f'', cu toleranta ''0.01'' | ||
+ | - Aproximatie pentru integrala unei functii pe intervalul ''[a,b]'' | ||
+ | * Scrieti o functie care aproximeaza valoarea integralei unei functii ''f'' intre ''a'' si ''b'', cu toleranta ''0.01''. Strategia de imbunatatire a unei aproximari consta in spargerea intervalului ''[a,b]'' in doua sub-intervale de dimensiune egala ''[a,m]'' si ''[m,b]'', calculul integralei pe fiecare, si adunarea rezultatului. | ||
+ | |||
+ | === Solutii === | ||
+ | [[https://github.com/Programming-Paradigms/Labs/archive/master.zip|Solutii (inclusiv pentru laboratorul 9)]] |