module Aula28 where import Control.Monad import System.IO.Unsafe data Caixa a = MkCaixa a deriving (Eq, Show) desencaixota :: Caixa a -> a desencaixota (MkCaixa val) = val runCaixa = desencaixota data Caixa' a = MkCaixa' { runCaixa' :: a } deriving (Eq, Show) -- não temos um desencaixotaMaybe :: Maybe a -> a ----- meuGetLine :: () -> IO String meuGetLine _ = getLine nome = getLine recebeNomeESauda :: IO () recebeNomeESauda = getLine >>= (\nome -> putStrLn ("Ola, " ++ nome)) -- main :: IO () -- main = recebeNomeESauda recebeNomeESaudaEducado :: IO () recebeNomeESaudaEducado = putStrLn "Qual seu nome?" >> -- usamos >> pois o resultado não nos interessa! getLine >>= -- usamos >>= pois queremos passar o resultado para adiante (\nome -> putStrLn ("Ola, " ++ nome)) -- "do" notation! recebeNomeESaudaEducadoDo :: IO () recebeNomeESaudaEducadoDo = do putStrLn "Qual seu nome?" nome <- getLine putStrLn $ "Ola, " ++ nome recebePalavraERepete :: IO [Char] recebePalavraERepete = do palavra <- getLine pure $ palavra ++ palavra recebePalavraERepeteBind :: IO [Char] recebePalavraERepeteBind = getLine >>= (\palavra -> pure (palavra ++ palavra)) -- palavraEmDobro = recebePalavraERepete -- palavraEmDobro :: IO [Char] -- Exemplo: list comprehension! pares :: [Integer] pares = [2*x | x <- [0..]] pares' :: [Integer] pares' = do x <- [0..] return (2*x) -- [2*x] impares :: [Integer] impares = do x <- [0..] guard (odd x) return x triplasPitagoricas :: [(Integer, Integer, Integer)] triplasPitagoricas = do x <- [1..] y <- [1..x] z <- [y..x] guard (x^2 == y^2 + z^2) return (y,z,x) triplasPitagoricasBind :: [(Integer, Integer, Integer)] triplasPitagoricasBind = [1..] >>= \x -> [1..x] >>= \y -> [y..x] >>= \z -> guard (x^2 == y^2 + z^2) >> return (y,z,x) -- -- -- "parear com a" é funtor ?! -- (b -> c) -> (a,b) -> (a,c) -- se a é Monoid, "parear com a" é Applicative? -- fun :: b -> c -- (val_a,fun) <*> (val_a', val_b) = (val_a `op` val_a', fun val_b) -- -- pure:: b -> (a,b) -- pure val_b = (mempty, val_b) -- se a é Monoid, "parear com a" é Monad? -- join :: (a,(a,b)) -> (a,b) -- join (val_a, (val_a', b)) = (val_a `op` val_a', b) -- (r ->) é Functor ?? -- fmap :: (a -> b) -> (r -> a) -> (r -> b) -- fmap fun_ab fun_ra = \val_r -> fun_ab (fun_ra val_ra) -- fmap = (.) -- (r ->) é Applicative?? -- pure :: a -> (r -> a) -- pure val_a = \val_r -> val_a -- pure = const -- o nome clássico é K (livro do Smullyan é Kestrel) -- (<*>) :: (r -> (a -> b)) -> (r -> a) -> (r -> b) -- fun_r_ab <*> fun_ra = \val_r -> (fun_r_ab val_r) (fun_ra val_r) -- (r ->) é Monad! Exercício :) -- Monad "Leitor" ou "Reader": ambiente de execução "read-only" data Leitor r a = MkLeitor {runLeitor :: r -> a} instance Functor (Leitor r) where fmap :: (a -> b) -> Leitor r a -> Leitor r b fmap fun_ab (MkLeitor fun_ra) = MkLeitor (fun_ab . fun_ra)