{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} {-# HLINT ignore "Use camelCase" #-} module Aula09 where -- notação alternativa -- equivalente a -- data Lista a = Vazia | Junta a (Lista a) -- deriving (Show, Eq) data Lista a where Vazia :: Lista a Junta :: a -> Lista a -> Lista a deriving (Show, Eq) -- data Natural = Zero | S Natural -- deriving (Show, Eq) data Natural where Zero :: Natural S :: Natural -> Natural deriving (Show, Eq) zero = Zero um = S zero dois = S um tres = S dois quatro = S tres cinco = S quatro seis = S cinco -- digamos que h é a composta de f e g -- h x = f $ g x -- ou -- h = f . g -- NÃO CONFUNDIR com h = f g -- !!! -- map (f . g) [1, 2, 3, 4] -- FUNÇÕES ANÔNIMAS -- (como lambda em python) f :: Integer -> Integer f x = (x*5) + 7 g :: Integer -> Integer g x = (x-49) ^ 3 h :: Integer -> Integer h = f . g k :: Integer -> Integer k = g . f h' :: Integer -> Integer h' = \ x -> f $ g x -- sintaxe: -- \ arg1 arg2 arg3 ... -> -- Condicionais -- 1) pattern matching (reconhecimento de padrão) mais2 :: Natural -> Natural -- mais2 Zero = S (S Zero) -- mais2 (S x) = S (S (S x)) -- mais2 = \ n -> S $ S n mais2 = S . S nome_bonito :: String -> Bool nome_bonito "Hugo" = False nome_bonito "Joaquim" = True nome_bonito _ = False -- 2) if-then-else clássico par :: Natural -> Bool par Zero = True par (S x) = if (par x) then False else True -- 3) case par' :: Natural -> Bool par' Zero = True par' (S x) = case (par' x) of True -> False False -> True data Sinais = Negativo | Nenhum | Positivo deriving Show sinal :: Integer -> Sinais sinal x = case x < 0 of True -> Negativo False -> case x == 0 of True -> Nenhum False -> Positivo -- 4) guardas (guards) sinal' :: Integer -> Sinais sinal' x | x < 0 = Negativo | x == 0 = Nenhum | otherwise = Positivo soma :: Natural -> Natural -> Natural soma x Zero = x soma Zero x = x soma (S x) (S y) = S $ S $ soma x y antecessor :: Natural -> Natural antecessor (S x) = x antecessor Zero = Zero -- nem precisava, ou qualquer valor fibo :: Natural -> Natural fibo x | x == Zero = Zero | x == S Zero = S Zero | otherwise = soma (fibo (antecessor (antecessor x))) (fibo (antecessor x)) -- -- Um pouco mais sobre listas -- List Comprehensions naturais = [0 ..] quadrados = [n^2 | n <- naturais] pares = [n | n <- naturais, even n] -- -- Algumas outras classes de tipos -- Já vimos: Show, Eq, Functor -- e um pouquinho de Num produto :: Natural -> Natural -> Natural produto _ Zero = Zero produto Zero _ = Zero produto (S x) (S y) = S $ soma (produto x y) (soma x y) deInteiro :: Integer -> Natural deInteiro x | x <= 0 = Zero | otherwise = S $ deInteiro (x-1) instance Num Natural where (+) = soma (*) = produto abs = id signum x = if x == Zero then 0 else 1 fromInteger = deInteiro negate = id -- e o contrário de deInteiro? paraInteiro :: Natural -> Integer paraInteiro Zero = 0 paraInteiro (S x) = (paraInteiro x) + 1 exemploDoido :: Natural -> String exemploDoido Zero = "Hugo" exemploDoido (S x) = (exemploDoido x) ++ (exemploDoido x) -- exemploDoido é "apenas" o homomorfismo único que sabemos que existe de (Natural, S, Zero) para (String, \ x -> x ++ x, "Hugo") -- !!!! fatorial :: Natural -> Natural fatorial Zero = S Zero fatorial (S x) = (S x) * (fatorial x) -- é o homomorfismo único que sabemos que existe de (Natural, S, Zero) para (Natural, ??? , S Zero) -- exercício: quem é "???" -- outras classes de tipos