module Aula26 where import Data.Function ( (&) ) import Control.Monad sauda = putStr "Oi la, qual seu primeiro nome? " >> getLine >>= \nome -> putStrLn ("Oi " ++ nome ++ ", muito prazer") -- notação "do" sauda_do = do putStr "Oi la, qual seu primeiro nome? " nome <- getLine putStrLn $ "Oi " ++ nome ++ ", muito prazer" sauda_mais :: IO () sauda_mais = do putStr "Oi, qual seu nome e idade? " nome <- getLine idade <- getLine putStrLn $ "Oi " ++ nome ++ ", você nasceu em " ++ show (2025 - (read idade)) -- list comprehensions naturais :: [Integer] naturais = [0..] pares :: [Integer] pares = [2*x | x <- naturais] impares = [x | x <- naturais, odd x] pares_do :: [Integer] pares_do = do x <- naturais return (2*x) pares_bind = naturais >>= \x -> return (2*x) impares_do = do x <- naturais -- não lembro :) -- adicionado após a aula: guard (odd x) return (x) impares_bind = naturais >>= \x -> if odd x then return x else [] --- de join para fish e bind meu_fish :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c) meu_fish f g val_a = join $ g <$> (f val_a) meu_bind :: Monad m => m a1 -> (a1 -> m a2) -> m a2 meu_bind a_encaixotado f = join (f <$> a_encaixotado) -- de bind para fish e join meu_join :: Monad m => m (m b) -> m b meu_join x = x >>= id meu_fish_2 :: Monad m => (a1 -> m a2) -> (a2 -> m b) -> a1 -> m b meu_fish_2 f g val_a = (return val_a) >>= f >>= g -- de fish para bind e join meu_bind_do_fish :: Monad m => m b -> (b -> m c) -> m c meu_bind_do_fish arg_encaixotado f = let fajuta () = arg_encaixotado in (fajuta >=> f) () -- meu_bind_do_fish arg_encaixotado f = (fajuta >=> f) () where -- fajuta () = arg_encaixotado meu_join_do_fish :: Monad m => m (m c) -> m c meu_join_do_fish mma = (fajuta >=> id) () where fajuta () = mma --- vejamos alguns exemplos de Monad -- "Logger" data Logador a = Log [String] a deriving (Show, Eq) instance Functor Logador where fmap :: (a -> b) -> Logador a -> Logador b fmap f (Log lista valor) = Log (lista ++ ["apliquei f"]) (f valor) instance Applicative Logador where pure :: a -> Logador a pure valor = Log [""] valor (<*>) :: Logador (a -> b) -> Logador a -> Logador b (Log log_fun fun) <*> (Log log_arg arg) = Log (log_arg ++ log_fun) (fun arg) instance Monad Logador where (>>=) :: Logador a -> (a -> Logador b) -> Logador b (Log log_arg arg) >>= f = let Log novo_log resultado = f arg in Log (log_arg ++ novo_log) resultado -- exemplo: soma_log :: Integer -> Integer -> Logador Integer soma_log x y = Log ["somei " ++ (show x)] (x+y) multiplica_log :: Integer -> Integer -> Logador Integer multiplica_log x y = Log ["multipliquei por " ++ (show x)] (x*y) resultado = (Log ["comecei com 2"] 2) >>= soma_log 3 >>= soma_log 4 >>= multiplica_log 5 main :: IO () main = putStrLn "Hello World!!!!!"