This is an old revision of the document!
====== Funcții ====== * Semnificatia termenului //aplicatie// * Definirea **functiilor anonime** in Haskell: <code haskell> \x1 x2 ... -> expr </code> * Curry vs uncurry (si de ce nu conteaza in Haskell) * **Inchideri functionale**: * definiti o functie care prefixeaza [1,2,3] la o lista primita ca parametru, ca o inchidere functionala ===== Funcții de ordin superior ===== Funcțiile de ordin superior sunt funcții care lucrează cu alte funcții: le primesc ca parametrii sau le returnează. Pentru a înțelege importanța lor, vom da următorul exemplu: ne propunem să scriem două funcții care primesc o listă și returnează, într-o nouă listă * toate elementele pare * toate elementele mai mari ca 10 <code haskell> evenElements [] = [] evenElements (x:xs) = if even x then x : evenElements xs else evenElements xs greaterThan10 [] = [] greaterThan10 (x:xs) = if x > 10 then x : greaterThan10 xs else greaterThan10 xs </code> <note> În loc de ''if'', puteți folosi următoarea sintaxă: <code haskell> myFunction x | x < 10 = "One digit" | x < 100 = "Two digits" | x < 1000 = "Three digits" | otherwise = "More than four digits" </code> </note> Testăm funcțiile scrise: <code> *Main> evenElements [1..20] [2,4,6,8,10,12,14,16,18,20] *Main> greaterThan10 [1..20] [10,11,12,13,14,15,16,17,18,19,20] </code> Observăm că funcțiile definite mai sus sunt foarte asemănătoare. De fapt, doar condiția verificată în ''if'' diferă. Scriem, deci, o funcție generală care primește o funcție pentru testarea elementelor: <code haskell> -- In primul pattern, nu folosim functia de testare, deci nu ne intereseaza ca aceasta -- sa fie legata la un nume, lucru marcat prin "_" myFilter _ [] = [] myFilter test (x:xs) = if test x then x : myFilter test xs else myFilter test xs </code> Acum putem rescrie funcțiile noastre, într-un mod mai elegant, utilizând funcția de filtrare: <code haskell> evenElements = myFilter even greaterThan10 = myFilter (> 10) </code> ===== Închideri funcționale ===== ''TODO'' ===== Currying vs. uncurrying ===== ''TODO'' ===== Funcții anonime ===== ''TODO'' ===== Exerciții ===== 1. Definiți o funcție de ordin superior care primește o funcție și un număr, și aplică de două ori funcția pe numărul respectiv. 2. Definiți o funcție care primește un operator binar, și întoarce același operator în care ordinea parametrilor a fost inversată //(e.g. 1/3 -> 3/1)// 3. Implementați și testați funcțiile: a) foldl b) foldr c) map d) filter e) zipWith f) compunerea de funcții (operatorul ''.'' din Haskell) <note tip> Dacă nu cunoașteți vreuna dintre funcții, o puteți căuta pe Hoogle pentru a vedea tipul și scopul ei. </note> 4. Implementați, folosind foldl sau foldr: a) map b) filter ===== Referințe ===== * [[Hoogle - motor de căutare pentru funcții Haskell|https://www.haskell.org/hoogle/]] * [[Higher order functions|https://wiki.haskell.org/Higher_order_function]] ===== Soluții laborator ===== - [[https://github.com/Programming-Paradigms/Labs/archive/master.zip | Solutii lab 2]] - Puteti, alternativ, sa folositi urmatorul repository git [[https://github.com/Programming-Paradigms/Labs]] pentru a descarca solutiile si le sincroniza, ulterior.