module C7 where -- construim un tip de date ca alias al unui alt tip type ListInt = [Int] -- construim un tip de date nou, ca enumerare de valori data FuzzyBoolean = CertainTrue | CertainFalse | Fuzzy -- construim un nou tip de date nou folosind constructori de bază. data Natural = Zero | Succ Natural deriving (Show, Eq) -- putem afișa la consolă și putem face == unu = Succ Zero doi = Succ unu --- important: vezi utilizare constructori de date în pattern-matching addNat Zero n = n addNat (Succ m) n = Succ $ addNat m n {- rulați addNat (Succ (Succ doi)) (Succ (Succ (Succ Zero))) addNat unu doi addNat doi Zero == doi :t addNat -} {- exemplu de expresie care nu poate fi tipată -} --f x = x x -- lucrare --m :: ? m f l | l == [] = [] | True = f (head l) + 1 : m f (tail l) ------------------------------------------------------- -- tree = [1, [tree]] -- > tip neuniform al elementelor din listă -- tree = (1, [tree]) -- > tip infinit pentru ultimele două elemente din pereche data Tree a = Nil -- arbore vid | Leaf a -- frunză | Node a [Tree a] -- nod cu un număr oarecare de copii getVal Nil = undefined getVal (Leaf x) = x getVal (Node x _) = x isNil Nil = True isNil _ = False treeOnes = Node 1 [treeOnes, treeOnes] -- arbore binar infinit care la BFS dă lista de numere -- mulțumesc pentru sugestia implementării unui coleg de-al vostru treeB = mkNode 1 where mkNode n = Node n $ map mkNode $ map (+(2*n)) [0, 1] {- varianta de la curs: treeB = Node 1 [stL 1, stR 1] where stL n = Node (2*n) [stL (2*n), stR (2*n)] stR n = let r=2*n+1 in Node r [stL r, stR r] -} preord :: Tree a -> [a] preord Nil = [] preord (Leaf x) = [x] preord (Node x children) = x : concatMap preord children limit :: Int -> Tree a -> Tree a limit 0 _ = Nil limit at t = case t of Node x children -> Node x $ map (limit (at-1)) children otherwise -> t instance Show a => Show (Tree a) where show tree = pt 0 tree where pt level tree = case tree of Nil -> space level ++ "- \n" Leaf val -> space level ++ show val ++ "\n" Node val children -> space level ++ show val ++ "\n" ++ if all isNil children then "" else concatMap (pt $ level + 1) children space sp = [' ' | _ <- [1..sp * 2]] isNil Nil = True isNil _ = False {- încercați la consolă limit 5 treeOnes limit 5 treeB take 10 $ preord treeB -- doar calea de pe partea stângă a arborelui, pentru că nu ne întoarcem niciodată preord $ limit 5 treeB -} data Graph a = G [(a, a)] graph = G [(1, 5), (1, 7), (1, 3), (3, 8), (4, 5), (4, 8), (5, 6), (8, 2), (8, 6), (8, 7)] outgoing x = map snd . (filter $ (== x) . fst) nodes (G []) = [] nodes (G (e:g)) = eNodes ++ (filter (not . (flip elem $ eNodes)) $ nodes $ G g) where eNodes = [fst e, snd e] exists _ Nil = False exists x (Leaf y) = x == y exists x (Node y l) = x == y || (or . (map $ exists x) $ l) -- toTree implementat doar pentru grafuri care pot fi parcurse integral pornind din primul nod din prima muchie. toTree g@(G edges) = purgeNil $ dfsFrom (head $ nodes g) [] where dfsFrom v visited | elem v visited = Nil | otherwise = case outgoing v edges of [] -> Leaf v children -> Node v subTrees where subTrees = foldl dfsChild [] children dfsChild previousTrees c = (dfsFrom c $ visited ++ concatMap preord previousTrees) : previousTrees purgeNil t = case t of (Node x children) -> Node x $ filter (not . isNil) $ map purgeNil children _ -> t -------------- vechi data Triple a = T a a a deriving (Show, Eq) first (T x _ _) = x second (T _ x _) = x third (T _ _ x) = x type TripleInt = Triple Int