import Data.List {- Problema urmărește lucrul cu un dicționar / map bidirecțional, în sensul că atât cheile, cât și valorile sunt unice în întregul dicționar. -} {- 1a. (3p) Definiți tipul de date. -} --data BidirectionalMap a b = Undefined data BidirectionalMap a b = BM [(a, b)] {- 1b. (2p) Definiți dicționarul gol. -} --emptyBM = undefined emptyBM = BM [] {- 1c. (5p) Implementați funcția getVal care caută valoarea corespunzătoare cheii date. -} getVal :: Eq a => a -> BidirectionalMap a b -> Maybe b --getVal = undefined getVal _ (BM []) = Nothing getVal key (BM ((x, y):rest)) | x == key = Just y | otherwise = getVal key $ BM rest {- 2a. (5p) Implementați funcția getKey care caută cheia corespunzătoare valorii date. -} getKey :: Eq b => b -> BidirectionalMap a b -> Maybe a --getKey = undefined getKey _ (BM []) = Nothing getKey second (BM ((x, y):rest)) | y == second = Just x | otherwise = getKey second $ BM rest {- 2b. (5p) Implementați funcția insBM care inserează o nouă corespondență în dicționar. Nu sunt inserate corespondențele care conțin o cheie sau o valoare deja existentă în dicționar. -} insBM :: (Eq b, Eq a) => a -> b -> BidirectionalMap a b -> BidirectionalMap a b --insBM = undefined insBM key value bm@(BM entries) | getVal key bm /= Nothing = bm | getKey value bm /= Nothing = bm | otherwise = BM $ (key, value) : entries {- 3. (10p) Instanțiați clasa Show astfel încât afișarea unui dicționar bidirecțional să prezinte atât corespondența de la chei la valori, cât și cea de la valori la chei. Corespondențele trebuie sortate lexicografic. Exemplu: > insBM 3 'a' $ insBM 2 'b' $ insBM 1 'c' emptyBM 'a' -> 3; 'b' -> 2; 'c' -> 1; 1 -> 'c'; 2 -> 'b'; 3 -> 'a'; -} instance (Show a, Show b) => Show (BidirectionalMap a b) where show (BM entries) = concat $ sort $ [ show x ++ " -> " ++ show y ++ "; " | (x, y) <- entries] ++ [ show y ++ " -> " ++ show x ++ "; " | (x, y) <- entries] {- Barem 1a. 2p: Sintaxă corectă data 1p: Asociere coerentă între chei și valori. 1b. 2p: Utilizare corectă constructor de date, dicționar gol. 1c. 1p: Utilizare corectă Nothing dacă nu găsește 3p: Parcurgere corectă a intrărilor 1p: Utilizare corectă a lui Just pentru a identifica valoarea. 2a. La fel ca la 1c 2b. 3p: verificare corectă că nu apare deja valoarea sau cheia 2p prima verificare; 1p a doua verificare 2p: inserare coerentă în structură a noii asocieri 3. 4p: sintaxă corectă pentru instanțiere 3p: compunere coerentă stringuri pentru intrări 2p: sortare rezultate 1p: asamblare corectă pentru ca rezultatul final să fie un string (concat sau similar) -}