-- încarc cu -- stack exec ghci -- :help -- :set prompt "λ> " -- :r (:reload) pentru reîncărcarea sursei -- :! com -- pentru rularea unei comenzi a sistemului de operare -- (e.g. :! clear / :! cls sau :! ls / :! dir) -- :t add1 -- (:type) -- află tipul oricărei expresii -- :t (+) -- pentru operatori trebuie dați în forma prefixată -- :: înseamnă "are tipul" -- v :: => tip = v are tipul tip, în contextul de tip -- de asemenea: -- :i add1 -- (:info) -- funcționează și pentru operatori, e.g. :i + -- Funcții -- \ stă pentru lambda -- în Haskell toți identificatorii încep cu literă MICĂ -- în Haskell CONTEAZĂ INDENTAREA -- \> :type 1 -- 1 :: Num a => a -- 1 este de un tip oarecare, cu condiția să fie un tip numeric -- \> :t 1.2 -- 1.2 :: Fractional a => a -- 1.2 este de un tip oarecare, cu condiția să fie fracțional -- \> :t True -- True :: Bool -- \> :t False -- False :: Bool add1 :: Num t => t -> t -> t add1 = \x y -> ((+) x y) add2 = \x y -> x + y -- în Haskell toate funcțiile sunt funcții curry add3 = \x -> \y -> x + y -- același tip cu cele dinainte incList l = map (\x -> x + 1) l -- PATTERN MATCHING add4 x y = x + y -- p-m incomplet (non-exhaustiv) addX 1 1 = 2 addX 2 3 = 5 addX 2 x = x + 2 -- addX 2 7 -> 9 -- addX 3 7 -> eroare -- transformare operator -> funcție (formă infixată -> formă prefixată add5 = (+) -- "add5 este același lucru cu funcția (+)" -- transformarea inversă: 1 `add5` 3 -- perechile și listele NU sunt același lucru -- toate elementele dintr-o listă sunt de același tip -- elementele dintr-un tuplu pot fi de tipuri diferite -- Perechi (acces cu fst și snd) -- \> (1, 'a') -- Tupluri -- \> ('a', [1,2,3], False) -- Liste, acces cu head și tail, funcții utile: (:), elem, (!!), (++) -- \> [1, 2, 3] -- \> [1..10] -- \> [1, -1..-20] -- setează pasul listei (rația progresiei aritmetice) -- \> ['a'..'z'] len1 l = if null l then 0 else 1 + len1 (tail l) len2 [] = 0 len2 (h : t) = 1 + len2 t len2b [] = 0 len2b (_ : t) = 1 + len2 t -- _ = nu ma intereseaza sa leg valoarea la un nume -- "dacă len2 este aplicat pe o listă care ar fi putut fi obținută prin aplicarea lui : -- între ceva și altceva, atunci leagă ceva la h și leagă altceva la t și evaluează -- corpul" -- parantezele sunt puse doar pentru asociativitate -- p-m face o legare a variabilelor din pattern în așa fel încât să se potrivească cu valoarea parametrului actual -- când apelez len2 [1,2,3], haskell leagă în așa fel încât [1,2,3] să fie rezultatul expresiei h:t -- "ce ar trebui să fie h și t astfel încât h:t -> [1,2,3] -- patternul arată cum ar fi putut fi construită valoarea dată ca argument -- și dacă patternul se potrivește, atunci se fac legările conform cu patternul len3 l = case l of [] -> 0 _ -> 1 + len3 (tail l) -- case este o expreise care întoarce o valoare len3b l = case l of [] -> 0 _:t -> 1 + len3b t -- gărzile pot fi folosite doar pentru a înlocui un = -- în gărzi pot pune condiții complete (în case pot pune doar patter-match pe valoarea unei variabile, după care fac case) len4 l | null l = 0 | otherwise = 1 + len4 (tail l) len4b l | null l = 0 | otherwise = 1 + len4b (tail l) len5 l = let t = tail l; lt = len5 t in if null l then 0 else 1 + lt len6 l | null l = 0 | otherwise = lt + 1 where lt = len6 t t = tail l -- let in este o expresiecare întoarce o valoare -- where se folosește împreună cu un = sau cu o serie de gărzi len7 [] = [] len7 [_] = 1 len7 (_:r@(_:_)) = len7 r + 1 maxList [] = undefined maxList [x] = x maxList (h:r@(_:_)) = max h $ maxList r fst3 (x,_,_) = x snd3 (_,x,_) = x thr3 (_,_,x) = x ----------------------------------- evensList l = filter even l sqevens l = map (**2) $ filter even l sqevens2 l = [x ** 2 | x <- l, even x] pairs = [(y, x) | x <- [1..20], even x, y <- [1..x], x `mod` y == 0] -- [(y, x) for x in range(20) if even(x) for y in range(x) if x % y == 0] -- x, ll listă de liste, în care dintre liste se găsește x lists = [[1,2,3,4], [2,4,6,8], [1,3,5,7], [7,4,7,4,3]] findX x ll = filter (\l -> elem x l) ll findX2 x ll = [l | l <- ll, elem x l] --mapFilter fM fF l = map fM (filter fF l) --mapFilter fM fF l = (map fM . filter fF) l mapFilter fM fF = map fM . filter fF -- variantă point-free. Nu menționez argumentul listă findXC x = filter (elem x) findXC2 :: Eq a => a -> [[a]] -> [[a]] findXC2 = filter . elem -- (define ones (stream-cons 1 ones)) ones = 1 : ones naturals = [1..] evens = zipWith (+) naturals naturals powOf2 = 1 : map (*2) powOf2 primes = sieve [2..] where sieve (p : xs) = p : sieve [x | x <- xs, x `mod` p /= 0] symbols = "abc" --expand alfa s = map (\y -> y : s) alfa --expand alfa s = (flip map) alfa (\y -> y : s) --expand alfa = (flip map) alfa . flip (:) expand = (flip (.) $ flip (:)) . flip map -- complet point-free pal s = reverse s == s bfs siruri fExp isGoal | null siruri = [] | isGoal current = current : other_solutions | True = other_solutions where current = head siruri other_solutions = bfs (tail siruri ++ fExp current) fExp isGoal palindromes alphabet = bfs [""] (expand alphabet) pal