import Data.List import Debug.Trace --------------------Programare point-free {- odds lst = filter odd lst odds lst = (filter odd) lst --asociativitate la stânga -} odds lst = filter odd lst --------------------Definiții point-free myLast :: [a] -> a myLast = head . reverse myMin :: Ord a => [a] -> a myMin = head . sort myMax :: Ord a => [a] -> a myMax = myLast . sort mySum :: Num a => [a] -> a mySum = foldl (+) 0 myAnd :: [Bool] -> Bool myAnd = foldl (&&) True myAny :: (a -> Bool) -> [a] -> Bool myAny = ((not . null) . ) . filter --ex --selectarea listelor nevide dintr-o listă de liste --[[],[1],[],[2,3]] ===> [[1],[2,3]] --evoluăm treptat de la varianta fără compunere la cea cu compunere notNull :: [[a]] -> [[a]] --notNull ls = filter (\l -> not (null l)) ls --notNull = filter (\l -> not (null l)) --notNull = filter (\l -> (not . null) l) --notNull = filter (not . null) 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 :: Num a => [[a]] -> [[a]] --replaceH ls = map (\l -> 1 : tail l) ls --replaceH = map (\l -> 1 : tail l) --replaceH = map (\l -> ((1 :) . tail) l) --replaceH = map ((1 :) . tail) replaceH = map $ (1 :) . tail --------------------Operatorul $ --de încercat în terminal --take 4 $ filter (odd . fst) $ zip [1..] [2..] --------------------Evaluare leneșă xs :: [Int] xs = [id 2, trace "8" 2*4] f x = trace "x" 2*x g x = f 2 + f 2 -- se evaluează de ? ori la apelul g 5 h x = x * x * x -- ? la apelul h (f 2) {- g 5 = h (f 2) = -} i x y = if y > 5 then y * y else x * x -- la apelul i (f 2) (f 3) ? --------------------Fluxuri {- (define naturals (let loop ((n 0)) (stream-cons n (loop (add1 n))))) -} naturals = loop 0 where loop n = n : loop (n+1) {- (define ones (stream-cons 1 ones)) -} ones = 1 : ones {- (define fibonacci (stream-cons 0 (stream-cons 1 (stream-zip-with + fibonacci (stream-rest fibonacci))))) -} fibonacci = 0 : 1 : zipWith (+) fibonacci (tail fibonacci) evens = filter even naturals --ex: 1/1, 1/2, 1/3... invNats = map (1/) [1 ..] --ex: 1, 1/(1*2), 1/(2*3), 1/(3*4)... invProds = 1 : zipWith (*) invNats (tail invNats) --------------------List comprehensions lc1 = [ (x,y,z) | x<-[1..3], y<-[1..4], x x ] --alte ex: {- Să se construiască mulțimea părților unei liste. Exemplu: pt lista [1,2,3]: [[], [1], [2], [3], [1,2], [1,3], [2,3], [1,2,3]] -} {- Să se construiască mulțimea partițiilor unui număr. Partiție a unui număr n = o listă de numere strict pozitive, ordonate crescător, a căror sumă este n. Exemplu: pt numărul 4: [[1,1,1,1], [1,1,2], [1,3], [2,2], [4]] -} {- Să se construiască fluxul de permutări: mai întâi permutări [1], apoi permutări [1,2] etc. Exemplu: take 3 permStream: [[[1]] [[2,1], [1,2]] [[3,1,2], [1,3,2], [1,2,3], [3,2,1], [2,3,1], [2,1,3]]] -}