import Data.List import Data.List.Ordered (minus, union, unionAll) import Debug.Trace --------------------Pattern matching fib :: Int -> Int fib 0 = 0 fib 1 = 1 fib n = fib (n-2) + fib (n-1) sumL :: [Int] -> Int sumL [] = 0 sumL (x:xs) = x + sumL xs --sumP :: (Int, Int) -> Int sumP (x,y) = x + y --ordered :: [Int] -> Bool ordered [] = True ordered [x] = True ordered (x:xs@(y:_)) = x <= y && ordered xs --ordered2 :: [Int] -> Bool ordered2 (x:xs@(y:_)) = x <= y && ordered2 xs ordered2 _ = True --ex: de implementat map si filter cu PM mapPM f [] = [] mapPM f (x:xs) = f x : mapPM f xs filterPM f [] = [] filterPM f (x:xs) = (if f x then [x] else []) ++ filterPM f xs --nu funcționează (din cauză că pattern-urile nu pot fi potrivite și între ele) --eq x x = True -- dă eroare Conflicting definitions for `x' --eq _ _ = False --------------------Compunere de funcții (operatorul .) --myLast :: [a] -> a myLast = head . reverse -- myLast [1..5] = 5 myMin :: Ord a => [a] -> a myMin = head . sort -- myMin [2,4,1,2,3,6,2] = 1 myMax :: Ord a => [a] -> a myMax = myLast . sort -- myMax [2,4,1,2,3,6,2] = 6 --ex --selectarea listelor nevide dintr-o listă de liste --[[],[1],[],[2,3]] ===> [[1],[2,3]] --notNull l = filter (\subL -> not (null subL)) l notNull l = (filter (not . null)) l -- notNull = filter (not . null) --înlocuirea cu 1 a head-ului fiecărei liste dintr-o listă de liste nevide --[[1],[2,3],[4,5,6]] ===> [[1],[1,3],[1,5,6]] --replaceH l = map (\subL -> 1 : tail subL) l --replaceH l = map (\subL -> ((:) 1) (tail subL)) l --replaceH l = map (((:) 1) . tail) l --replaceH = map (((:) 1) . tail) --replaceH = map ((1:) . tail) replaceH = map $ (1:) . tail --------------------Operatorul $ --de încercat în terminal --take 4 $ filter (odd . fst) $ zip [1..] [2..] --------------------Expresii condiționale --uglySum :: [Int] -> Int uglySum l = if null l then 0 else head l + uglySum (tail l) --myTranspose :: [[a]] -> [[a]] -- [[1,2,3], [4,5,6], [7,8,9]] ===> -- [ [2,3], [5,6], [8,9]] ===> -- [ [3], [6], [9]] ===> -- [ [], [], []] myTranspose matrix = case (head matrix) of [] -> [] _ -> map head matrix : myTranspose (map tail matrix) myT ([]:_) = [] myT matrix = map head matrix : myTranspose (map tail matrix) --ex: de implementat filter cu case filterCase f l | null l = [] | True = (case f e of True -> [e] _ -> []) ++ filterCase f (tail l) where e = head l --allEqual :: Eq a => a -> a-> a-> Bool allEqual a b c | a==b = b==c | otherwise = False --ex: de implementat filter cu pattern matching și gărzi --------------------Legări locale myFoldl :: (b -> a -> b) -> b -> [a] -> b myFoldl f acc [] = acc myFoldl f acc (x:xs) = let newAcc = f acc x -- în Haskell, funcția lui foldl primește acc ca parametru stâng! in myFoldl f newAcc xs myFoldr :: (a -> b -> b) -> b -> [a] -> b myFoldr f acc [] = acc myFoldr f acc (x:xs) = f x rightResult where rightResult = myFoldr f acc xs exwhere = a + b + c + d --7+1+2+6 = 16 where a = 2+5 (b, c) = head (zip [1..] [2..]) -- (b,c) = (1,2) => b=1, c=2 d = f 5 where f = (+1) --ex: de implementat filter cu pattern matching, gărzi și where filterg :: (a -> Bool) -> [a] -> [a] filterg f (x:xs) | f x == True = [x] ++ filterg f xs | otherwise = filterg f xs filterg f [] = [] --------------------Evaluare leneșă f x = trace "x" 2*x g x = f 2 + f 2 -- se evaluează de 2 ori la apelul g 5 h x = x*x*x -- evaluare leneșă la apelul h (f 2) i x y = if y>5 then y*y else x*x --------------------Fluxuri naturals = let loop n = n : loop (n+1) in loop 0 ones = 1 : ones fibonacci = 0 : 1 : zipWith (+) fibonacci (tail fibonacci) evens = filter even naturals --ex: 1/1, 1/2, 1/3... --ex: 1, 1/(1*2), 1/(2*3), 1/(3*4)... --------------------List comprehensions lc1 = [ (x,y) | x<-[1..3], y<-[1..4] ] fibo = 0 : 1 : [ x+y | (x,y) <- zip fibo (tail fibo) ] --ex: de implementat map si filter cu list comprehensions map' f l = [f x | x <- l] filter' f l = [x | x <- l, f x] primes' = 2 : 3 : minus [5,7..] (unionAll [[p*p, p*p+2*p..] | p <- tail primes']) seriesUp :: Int -> [Int] seriesUp n = concatMap (\x -> [1..x]) [1..n] qsort [] = [] qsort (x:xs) = qsort [ y | y<-xs, y<=x] ++ [x] ++ qsort [ y | y<-xs, y>x]