import Debug.Trace import System.Random -- comenzile din comentarii care încep cu -- \> sunt de scris la consolă -- :help (sau :?) -- :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ă -- de asemenea: -- :i add1 -- (:info) -- funcționează și pentru operatori, e.g. :i + -- Tipuri de date -- \> :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 -- \> :t [1,2,3] -- [1,2,3] :: Num t => [t] -- este o listă de elemente de tip t, iar t este un tip numeric -- \> :t (1, 'a') -- (1, 'a') :: Num t => (t, Char) -- o pereche -- \> :t (1, 'a', True, [5..9]) -- un tuplu -- (1, 'a', True, [5..9]) :: (Num t1, Num t, Enum t1) => (t, Char, Bool, [t1]) -- definire directă a funcției add1 :: Num t => t -> t -> t -- necesar pentru că sinteza de tip determină că add1 este pe întregi add1 = \x y -> ((+) x y) -- (add1 1 2) -- ((add1 1) 2) -- add1 1 2 -- \> :t add1 add2 = \x -> \y -> (((+) x) y) -- cu toate parantezele și în formă curry, dar ne-necesar add3 = \x y -> x + y -- pattern-matching add4 x y = x + y -- p-m incomplet (non-exhaustiv) addX 1 2 = 3 addX 1 x = x + 1 addX 5 6 = 11 -- transformare operator -> funcție (formă infixată -> formă prefixată add5 = (+) -- transformarea inversă: 1 `add5` 3 -- aplicare parțială add6 x = (+ x) -- Perechi (acces cu fst și snd) -- \> (1, 'a') -- Tupluri -- \> ('a', [1,2,3], False) -- Tripluri: acces prin p-m fst3 (x, _, _) = x -- mă aștept ca argumentul lui fst3 să fie un triplu, și voi lega elementele triplului la numele x, y, z mid3 (_, y, _) = y lst3 (_, _, z) = z -- 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 l == [] then 0 else 1 + len1 (tail l) -- pattern-matching len2 [] = 0 -- primește o listă care a fost obținută prin operația e:t len2 (e : t) = 1 + len2 t -- parantezele sunt **pentru asociativitate** len2b [] = 0 len2b (_:t) = 1 + len2 t -- _ = nu mă interesează să leg valoarea la un nume -- patterns non-exhaustive len2c [] = 0 len2c [_] = 1 -- case len3 lista = case lista of [] -> 0 _:t -> 1 + len3 t len3b lista = case lista of _:t -> 1 + len3b t otherwise -> 0 len3c l=case l of _:t->1+len3c t; _->0 -- gărzi (vedeți https://wiki.haskell.org/Pattern_guard ) len4 lista | lista == [] = 0 | otherwise = 1 + len4 (tail lista) len5 lista | lista==[]=0 | True=1+len5(tail lista) len6 lista | lista==[]=0 | True = let {t=(tail lista);lt=len6 t} in 1 + lt len7 lista | lista == [] = 0 | otherwise = 1 + lt where -- indentat mai puțin decât gărzile lt = len7 t t = tail lista sumList [] = 0 sumList (h:t) = h + sumList t maxList [x] = x maxList (h:t) = max h (maxList t) -- altă variantă maxList2 [] = undefined maxList2 [x] = x maxList2 (h:rest@(_:_)) = max h $ maxList2 rest maxList3 (h : (e:r)) = max h $ maxList2 t where t=e:r -- fluxuri ones = 1 : ones naturals = let natFrom start = start : natFrom (start + 1) in natFrom 0 naturals2 = 0 : zipWith (+) ones naturals2 -- List comprehensions evens = [x | x <- [0..], mod x 2 == 0] multiples n = [x | x <- [1..], mod x n == 0] cart l1 l2 = [(x, y) | x <- l1, y <- l2] squareMult d = [(n, n * n) | n <- [0..], n `mod` d == 0] primes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p /= 0] -- sau --p : sieve (filter (\x -> mod x p /= 0) xs) -- sau --p : sieve (filter ((/= 0) . (flip mod $ p)) xs) symbols = ['a'..'c'] -- "a, b, c, aa, bb, cc, aaa, aba, aca, bab, ..." palindrome3 s = len1 s == 3 && s == reverse s palindrome s = s == reverse s -- a, b, c -- aa, ab, ac ba, bb, bc, ca, cb, cc -- aaa, aab, aac, .... aca, acb, acc, baa, bab, .... --aacabba -> aaacabba baacabba caacabba --expandString s = map (\symb -> symb : s) symbols expandString s = map (flip (:) $ s) symbols --expandString s = map (\symb -> trace ("\nBuild "++show symb++"+"++s++"\n") $ symb : s) symbols -- cu limitarea lungimii șirurilor: --expandString s = filter (\sir -> length sir < 3) (map (\symb -> symb : s) symbols) --expandString s = filter ((< 4) . length) $ map (flip (:) $ s) symbols --((f . g) x) = f (g x) -- f $ x = (f x) -- BFS {- -- prima soluție: bfs init expand isGoal = let search frontiera | frontiera == [] = undefined | isGoal cState = cState | otherwise = search (tail frontiera ++ expand cState) where cState = head frontiera in search [init] --} --{- -- toate soluțiile bfs init expand isGoal = let search frontiera | frontiera == [] = [] | isGoal cState = cState : other_sols | otherwise = other_sols where cState = head frontiera other_sols = search (tail frontiera ++ expand cState) in search [init] --} -- bfs "" expandString palindrome3 -- bfs "" expandString palindrome -- toate palindroamele -- take 100 $ bfs "" expandString palindrome -- primele 100 palindroame {- add x y = ((+) x) y add x = (+) x add = (+) -- point-free programming -- λx.corp -}