This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
laboratoare:04-tipuri-de-date-abstracte [2016/03/20 22:51] mihai.dumitru2201 Sections |
laboratoare:04-tipuri-de-date-abstracte [2016/03/24 14:54] (current) mihai.dumitru2201 Correction |
||
|---|---|---|---|
| Line 7: | Line 7: | ||
| Scopul laboratorului: | Scopul laboratorului: | ||
| * Recapitularea conceptului de TDA | * Recapitularea conceptului de TDA | ||
| - | * Definirea unor TDA-uri în Haskell | + | * Definirea de TDA-uri în Haskell |
| * Familiarizarea cu conceptul de TDA-uri polimorfice | * Familiarizarea cu conceptul de TDA-uri polimorfice | ||
| + | * Introducerea tipului de date ''Maybe'' | ||
| Line 16: | Line 17: | ||
| Un TDA familiar este **list**. În primul laborator am lucrat cu liste de întregi, definind o listă ca fiind fie lista vidă, fie un întreg introdus în altă listă. Deasemena am definit o mulțime de operații posibile pe listă: ''isEmpty'', ''head'', ''tail'', ''add'', ''get'', ''ins'', ''show''.\\ | Un TDA familiar este **list**. În primul laborator am lucrat cu liste de întregi, definind o listă ca fiind fie lista vidă, fie un întreg introdus în altă listă. Deasemena am definit o mulțime de operații posibile pe listă: ''isEmpty'', ''head'', ''tail'', ''add'', ''get'', ''ins'', ''show''.\\ | ||
| - | Pentru a lucra cu liste într-un limbaj ca C, am scris două //implementări// distincte, și anume ''LinkedList'' și ''ArrayList''. Ambele implementări respectă specificațiile din primul paragraf. | + | Pentru a lucra cu liste într-un limbaj ca Java, am scris două //implementări// distincte, și anume ''LinkedList'' și ''ArrayList''. Ambele implementări respectă specificațiile din primul paragraf. |
| <note important> | <note important> | ||
| - | Unii autori includ în descrierea TDA-urilor și complexități. Din acest punct de vedere, implementările pentru | + | Unii autori includ în descrierea TDA-urilor și complexități. Din acest punct de vedere, implementările |
| ''LinkedList'' și ''ArrayList'' diferă. | ''LinkedList'' și ''ArrayList'' diferă. | ||
| </note> | </note> | ||
| - | === Constructori === | + | ==== Constructori ==== |
| Valorile posibile ale unui TDA sunt date de constructorii acestuia.\\ | Valorile posibile ale unui TDA sunt date de constructorii acestuia.\\ | ||
| Line 62: | Line 63: | ||
| Observăm prezența a două pattern-uri: unul pentru arborele vid, celălalt pentru un nod, într-un fel foarte asemănător cu modul în care lucram cu liste, făcând pattern matching pe ''[]'' și ''(x:xs)''. | Observăm prezența a două pattern-uri: unul pentru arborele vid, celălalt pentru un nod, într-un fel foarte asemănător cu modul în care lucram cu liste, făcând pattern matching pe ''[]'' și ''(x:xs)''. | ||
| - | |||
| - | |||
| - | === Exercițiu === | ||
| - | |||
| - | 1. Implementați TDA-ul pentru propria voastră listă care poate conține doar numere întregi. | ||
| <note tip> | <note tip> | ||
| Line 92: | Line 88: | ||
| </code> | </code> | ||
| </note> | </note> | ||
| + | |||
| + | ==== Exerciții TDA ==== | ||
| + | |||
| + | 1. Implementați TDA-ul pentru propria voastră listă care poate conține doar numere întregi. | ||
| 2. Scrieți o funcție care convertește valori ale TDA-ului vostru în liste din Haskell. | 2. Scrieți o funcție care convertește valori ale TDA-ului vostru în liste din Haskell. | ||
| Line 106: | Line 106: | ||
| 3. Implementați TDA-ul "optiune", care codifică valori opționale de tip Integer (e.g. fie ''None'', fie o valoare întreagă). | 3. Implementați TDA-ul "optiune", care codifică valori opționale de tip Integer (e.g. fie ''None'', fie o valoare întreagă). | ||
| + | <note> | ||
| + | Pentru a ilustra importanța acestui TDA, considerăm următoare situație: vrem să implementăm o funcție care returnează valoarea păstrată în rădăcina unui arbore dat. | ||
| + | |||
| + | <code haskell> | ||
| + | -- presupunem ca Optiune are constructorii "None" si "Value Int" | ||
| + | rootValue :: Tree -> Optiune | ||
| + | rootValue Nil = None | ||
| + | rootValue (Node v _ _) = Value v | ||
| + | </code> | ||
| + | |||
| + | Un arbore vid nu are nicio valoare în rădăcină, iar pentru orice alt arbore, valoarea este cea din nodul primit. Fără TDA-ul ''Optiune'' nu am putea avea pattern-uri exhaustive, fără să folosim convenții de valori speciale (e.g. 0, MAX_INT) pentru valoarea din rădăcină. | ||
| + | |||
| + | Putem scrie o funcție care ia o ''Optiune'' și returnează un șir pentru printare. Combinăm apoi cele două funcții: | ||
| + | |||
| + | <code haskell> | ||
| + | pretty :: Optiune -> String | ||
| + | pretty None = "No value" | ||
| + | pretty (Value v) = "Value is " ++ show v | ||
| + | |||
| + | printRootValue :: Tree -> String | ||
| + | printRootValue = pretty . rootValue | ||
| + | </code> | ||
| + | |||
| + | Încărcăm modulele în ghci și voilà: | ||
| + | <code> | ||
| + | *Main> printRootValue (Node 1 (Node 1 Nil (Node 2 Nil Nil)) (Node 3 (Node 4 (Node 5 Nil Nil) Nil) (Node 6 Nil Nil))) | ||
| + | "Value is 1" | ||
| + | *Main> printRootValue Nil | ||
| + | "No value" | ||
| + | </code> | ||
| + | </note> | ||
| + | |||
| + | <note tip> | ||
| + | Evident, Haskell pune la dispoziție un tip de date similar, numit ''Maybe''. Spre deosebire de tipul nostru, ''Maybe'' funcționează cu orice tip de date, nu doar întregi, fiind un tip //polimorfic// (mai multe detalii [[laboratoare:04-tipuri-de-date-abstracte#tda-uri_polimorfice|aici]]). | ||
| + | |||
| + | <code haskell> | ||
| + | data Maybe a = Nothing | Just a | ||
| + | </code> | ||
| + | </note> | ||
| - | === Înregistrări === | + | ==== Înregistrări ==== |
| Vrem să definim un TDA pentru a descrie un student, folosind următoarele câmpuri: nume, prenume, an de studiu, medie. | Vrem să definim un TDA pentru a descrie un student, folosind următoarele câmpuri: nume, prenume, an de studiu, medie. | ||
| Line 157: | Line 196: | ||
| e) Scrieți o funcție care primește o listă de nume, o listă de vârste, o listă ce conține liste de prieteni, și întoarce o listă de înregistrări corespunzătoare. | e) Scrieți o funcție care primește o listă de nume, o listă de vârste, o listă ce conține liste de prieteni, și întoarce o listă de înregistrări corespunzătoare. | ||
| - | |||
| - | !! In acest laborator, vom specifica explicit tipurile functiilor implementate !! | ||
| ===== TDA-uri polimorfice ===== | ===== TDA-uri polimorfice ===== | ||
| Line 191: | Line 228: | ||
| </code> | </code> | ||
| - | === Constante polimorfice === | + | ==== Constante polimorfice ==== |
| Care este tipul listei vide? | Care este tipul listei vide? | ||
| Line 240: | Line 277: | ||
| <code haskell> | <code haskell> | ||
| - | List a = Empty | Cons a (List a) | + | data List a = Empty | Cons a (List a) |
| </code> | </code> | ||
| Line 250: | Line 287: | ||
| </note> | </note> | ||
| - | === Exerciții === | + | ==== Exerciții TDA-uri polimorfice ==== |
| + | |||
| + | <note important> | ||
| + | Încercați să vă obișnuiți să scrieți explicit tipurile tuturor funcțiilor definite de voi în continuare. | ||
| + | </note> | ||
| 5. Pornind de la TDA-ul polimorfic ''List a'' definit mai sus: | 5. Pornind de la TDA-ul polimorfic ''List a'' definit mai sus: | ||
| Line 257: | Line 298: | ||
| b) Implementați ''foldl'', ''foldr'' și ''map'' pentru TDA-ul creat. | b) Implementați ''foldl'', ''foldr'' și ''map'' pentru TDA-ul creat. | ||
| - | \\ | ||
| \\ | \\ | ||
| 6. a) Implementați TDA-ul pentru arbori polimorfici.\\ | 6. a) Implementați TDA-ul pentru arbori polimorfici.\\ | ||
| Line 267: | Line 307: | ||
| g) Implementați ''tmap'' pe baza ''foldT''.\\ | g) Implementați ''tmap'' pe baza ''foldT''.\\ | ||
| - | \\ | ||
| \\ | \\ | ||
| 7. a) Implementați TDA-ul ''Pereche'', care poate conține două valori de orice tip.\\ | 7. a) Implementați TDA-ul ''Pereche'', care poate conține două valori de orice tip.\\ | ||
| b) Implementați o funcție care primește două liste (reprezentate folosind TDA-ul anterior) și construiește o listă de perechi. | b) Implementați o funcție care primește două liste (reprezentate folosind TDA-ul anterior) și construiește o listă de perechi. | ||
| + | ===== Referințe ===== | ||
| + | |||
| + | * [[https://wiki.haskell.org/Abstract_data_type|ADT - Haskell wiki]] | ||
| + | * [[https://wiki.haskell.org/Maybe|Maybe - Haskell wiki]] | ||
| - | === Solutii laborator === | + | ===== Soluții laborator ===== |
| - | * [[https://github.com/Programming-Paradigms/Labs/archive/master.zip|Rezolvari]] | + | * [[https://github.com/Programming-Paradigms/Labs/archive/master.zip|Rezolvări]] |