import System.Directory -- kvoli 4.10 import Data.Char -- kvoli 4.11 {- 4.1 foldr (.) id - zistime si typy vsetkych funkcii (a kazdy vyskyt osobitne) foldr :: (a -> b -> b) -> b -> [a] -> b (.) :: (a -> b) -> (c -> a) -> c -> b id :: a -> a - premenujeme typove premenne, aby mal kazdy typ vlastne foldr :: (a -> b -> b) -> b -> [a] -> b (.) :: (d -> e) -> (f -> d) -> f -> e id :: c -> c - urcime typove rovnosti na zaklade aplikacii (d -> e) -> (f -> d) -> f -> e = a -> b -> b c -> c = b - rozpiseme typove rovnosti do jednoduchsich d -> e = a f -> d = b f -> e = b c -> c = b - vyjadrime si premenne pomocou co najmensieho poctu premennych d = e = f = c b = c -> c a = c -> c - zistime, ak typ vlastne hladame ([a] -> b) a dosadime zan vyjadrenie premennych ziskane v predchadzajucom kroku foldr (.) id :: [a] -> b = [c -> c] -> c -> c - ukazky pouzitia: foldr (.) id [(+4), (*10), (42^)] foldr (.) id [(+4), (*10), (42^)] 1 -} {- 4.2 ako 4.1 -} {- 4.3 -} subtractlist = foldl1 (-) -- ina moznost, ale menej pekna: subtractlist2 (h:s) = foldl (-) h s {- 4.4 http://nl.wikipedia.org/wiki/Fold -} {- 4.5 - ukazka, ako blbo sa daju zvolit argumenty tak, aby nam to dalo minimalnu informaciu o tom, co ta funkcia robi, ze? Prelude> foldr (:) [1,1,1] [1,1,1] [1,1,1,1,1,1] - rozumnejsi priklad Prelude> foldr (:) [1,2,3] [4,5,6] [4,5,6,1,2,3] - prepiseme si zoznam na skutocnu podobu, aby bolo lahko vidiet, ako sa to prepise katamorfizmovym stylom podla obrazka zo 4.4 Prelude> foldr (:) [1,2,3] (4:5:6:[]) [4,5,6,1,2,3] - snazime sa zistit, ako upravit vyssie uvedenu funkciu tak, aby fungovala ako (++)... zly sposob :) Prelude> foldl (flip (:)) [1,2,3] (4:5:6:[]) [6,5,4,1,2,3] - a dobry sposob Prelude> flip (foldr (:)) [1,2,3] (4:5:6:[]) [1,2,3,4,5,6] -} {- 4.6 -} data Teleso = Kvadr Float Float Float | Valec Float Float | Nic deriving Show -- nutne kvoli moznosti zobrazit hodnty objem :: Teleso -> Float objem (Kvadr a b c) = a * b * c objem (Valec r v) = pi * r * r * v objem Nic = 0 -- pi pouzite vo vzorci je standardne dostupna konstanta {- 4.7 -} -- data Maybe a = Nothing | Just a divlist :: [Float] -> [Float] -> [Maybe Float] divlist = zipWith (\x y -> if y == 0 then Nothing else Just (x/y)) -- tu to nie je kriticke, ale takato technika sa da pouzit na vyhnutie sa -- vynimke, ak by sme chceli robit napriklad map head [[1], [2,3], [], [4]], -- pricom v neosetrenom pripade by to skrachovalo pri volani head [] {- 4.10 -} -- import na zaciatku suboru vypis_obsahu :: IO () vypis_obsahu = do putStr "zadaj meno: " jmeno <- getLine ex <- doesFileExist jmeno if ex then do obsah <- readFile jmeno putStrLn obsah else error "soubor neexistuje" {- 4.11 -} -- import na zaciatku suboru pr411 = getLine >>= putStr . filter isAlpha pr411_2 = getLine >>= \x -> putStr (filter isAlpha x) pr411_3 = do x <- getLine putStrLn (filter isAlpha x) {- 4.12 -} query = putStr otazka >> getLine >>= \odpoved -> return (odpoved == "ano") {- BONUSOVA ULOHA Zadanie: (stacilo spravit jednu) 1. Prepiste nasledujuci vyraz na prehladnejsi: getLine >>= return . (++) >>= (\x -> getLine >>= return . x) >>= putStrLn 2. Napiste funkciu typu String -> (String -> IO ()) -> IO (), ktora ma ako argumenty retazec a nejaku akciu. Funguje tak, ze postupne vypisuje chvosty retazca a za kazdym vypisom chvostu zavola akciu na nom. T. j. na retazci "ab" vykona v tomto poradi: vypis "ab", zavola akciu na "ab", vypise "b", zavola akciu na "b", vypise "" a zavola akciu na "". Riesenie: 1. cielom bude previest si vyraz na do notaciu a na to potrebujeme previest jednotlive casti na pointwise: getLine >>= (\t -> return ((++) t)) >>= (\x -> getLine >>= (\y -> return (x y))) >>= \m -> putStrLn m odstranenie zatvoriek okolo lambda abstrakcii - definovane premenne budu platit az do konca riadka, co nam nevadi; tento krok nie je uplne korektny, ale vzhladom na to, ze nedojde k ziadnej semantickej zmene, dovolime si ho spravit, inac by vysledny zapis bol zbytocne neprehladny getLine >>= \t -> return ((++) t) >>= \x -> getLine >>= (\y -> return (x y) >>= \m -> putStrLn m a prepiseme do do notacie: do t <- getLine x <- return ((++) t) y <- getLine m <- return (x y) putStrLn m nahradime zapisy "var <- return vyraz" za ekvivalentne "let var = vyraz" do t <- getLine let x = (++) t y <- getLine let m = x y putStrLn m odstranime let dosadenim vyrazov do t <- getLine y <- getLine putStrLn ((++) t) y a vysledok je takyto: do x <- getLine y <- getLine putStrLn (x ++ y) 2. doer :: String -> (String -> IO ()) -> IO () doer "" f = putStrLn "" >> f "" doer s f = putStrLn s >> f s >> doer (tail s) f -}