Sveučilište u Zagrebu Fakultet elektrotehnike i računarstva PROGRAMIRANJE U HASKELLU Ak.god. 2011/12. LEKCIJA 2: if-then-else, liste v1.0 (c) 2011 Jan Šnajder ============================================================================== > import Data.Char > import Data.List === KONSTRUKT IF-THEN-ELSE =================================================== > condDec x = if x > 0 then x - 1 else x > foo x = (if even x then x*2 else 2) + 1 Nije isto kao: > foo' x = if even x then x*2 else 2 + 1 > bigNumber x = if x >= 1000 then True else False Izbjegavajte vraćati konstante True/False; umjesto toga jednostavno vratite Booleov izraz. > bigNumber' x = x >= 1000 Nešto sa stringovima: > merge s1 s2 = s1 ++ (if s1 < "m" then " nije " else " je ") ++ s2 > merge2 s1 s2 = > s1 ++ " " ++ (if s1 < "m" then "ni" else "") ++ "je " ++ s2 Guardovi (čuvari): > merge3 s1 s2 | s1 < "m" = s1 ++ "je" ++ s2 > | otherwise = s1 ++ "nije " ++ s2 > grade score | score < 50 = 1 > | score < 63 = 2 > | score < 76 = 3 > | score < 89 = 4 > | otherwise = 5 > showSalary amount bonus > | bonus /= 0 = "Plaća je " ++ show amount ++ ", a bonus " ++ show bonus > | otherwise = "Plaća je " ++ show amount === VJEŽBA 1 ================================================================ 1.1. - Napišite funkciju concat3 koja konkatenira tri stringa, ali ispušta srednji ako je kraći od 2 znaka (funkcija 'length'). - Proširite uvjet: kraća od 2 znaka ili dulja od 7 znakova. 1.2. - Napišite showSalary jednostavnije (sa samo jednim if-then-elsom) - dodajte provjeru da plaća ne može biti negativna (ispišite poruku). Pazite gdje ćete dodati taj slučaj. - Ispišite i total (plaća+bonus). 1.3 - Napišite funkciju koja broj ispisuje riječima (koristite čuvare) - Napišite novu funkciju koja dvoznamenkasti broj ispisuje riječima (npr. 23 -> "dvadeset i tri"). === LISTE ==================================================================== > l1 = [1,2,3] Operator ':' (tzv. "cons"): > l1' = (1:(2:(3:[]))) > l1'' = 1:2:3:[] Konkatenacija (povezivanje) listi: > l2 = [1,2,3] ++ [4,5,6] > myConcat l1 l2 = l1 ++ l2 Pretvaranje elementa u listu: > listify x = [x] > listify' x = x:[] Dijelovi liste: head, tail, init, last. Uzimanje ili odbacivanje početka liste: > l3 = take 3 [9,2,10,3,4] > l4 = drop 3 [9,2,10,3,4] Obrtanje liste: > l5 = reverse [1,2,3] I znakovni nizovi su liste: > l6 = "ovo je lista" > l7 = head l3 > l8 = 'H' : "askell" Je li znakovni niz palindrom? > isPalindrome s = s == reverse s Liste su obavezno homogene. Ne može biti: [1,'a',3]. Replicate, cycle i repeat: > l9 = repeat 'a' > l10 = cycle [1,2,3] > l11 = replicate 10 'a' Kako napraviti 'replicate' pomoću 'repeat'? > replicate' n x = take n $ repeat x Rasponi: > l12 = [1..100] > l13 = [1,3..999] > l14 = take 10 [1,2..100] > l15 = [1..] > l16 = ['a'..'z'] Lijenost na djelu: > l17 = take 10 [1..] > l18 = head [1..] Što se ovdje događa?: > l19 = tail [1..] > n = length [1..] Lista bez prvog i zadnjeg znaka: > trim l = tail (init l) > trim' l = init $ tail l > blanks = repeat ' ' > padTo10 s = s ++ take (10 - length s) blanks Paziti na ovo: > l20 = head [] Liste listi: > l21 = [[1,2,3],[4,5,6],[7,8,9,10]] > l22 = ["red","green","blue"] Oprez! Liste su homogene, pa ne može biti [1,2,[3,4]] niti ["red",'a']. Concat: > l23 = concat l21 Minimum i maksimum u listi: > m1 = minimum [4,1,2,3] > m2 = maximum "Haskell for the win!" Dohvaćanje elemenata liste: > x = [1,3..100] !! 17 > y = l21 !! 1 !! 2 Vlastita izvedba funkcije 'chr': > intToChar i = ['A'..] !! (i - 65) Što se događa ako i < 65 ? > intToChar' i | i >=65 = ['A'..] !! (i - 65) > | otherwise = error "Invalid index" Logičke operacije nad listom: > r1 = and [True,True,False] > r2 = or [True,True,False] Izbacivanje duplikata -- funkcija 'nub': > l24 = nub [1,2,3,1,1,2] > l25 = nub "Svako slovo samo jednom!" Sortiranje liste: > l26 = sort [1,4,5,6,1,2] > l27 = sort "Abeceda" === VJEŽBA 2 ================================================================ 2.1. - Napravite funkciju koja vraća listu bez prva 3 i zadnja 3 znaka. 2.2. - Napravite funkciju 'initals s1 s2' koja uzima ime i prezime osobe i vraća znakovni niz inicijala. Npr. initials "Gabi Novak" => "G. N." 2.3. - Napravite funkciju koja konkatenira dva stringa, ali tako da dulji string uvijek bude prvi. 2.4. - Nadogradite 'padTo10' u 'padToN' tako da uzima argumente 'n' (duljina proširenog stringa) i 'x' (padding character). - Nadogradite padToN tako da, ako je duljina stringa veća od 'n', da ga skraćuje na n znakova. 2.5. - Napravite funkciju 'makeStr s1 s2' koja generira ovakav string: s1{3}s2's1'* gdje s2' je obrnut string od s2', s1' je s1 bez prvog znaka, {3} označava ponavljanje 3x, a '*' je ponavljanje beskonačno mnogo puta. 2.6. - Napravite funkciju 'safeHead l': funkcija vraća praznu listu ako je l prazna, a inače vraća [x], gdje je x prvi element. 2.7. - Napravite funkciju 'mkMatrix m n' koja generira matricu mxn (matrica prikazana kao lista listi) i popunjava je nulama (koristite 'replicate'). 2.8. - Napravite funkciju koja provjerava ima li u listi ponavljajućih znakova (koristite 'nub'). 2.9. - Napravite funkciju 'pangram s' koja provjerava je li znakovni niz pangram (svako slovo abecede koristi se barem jednom). Pretpostavite da je niz pisan malim slovima. Hint: koristite 'nub' i 'sort'.