{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} {-# HLINT ignore "Use camelCase" #-} module Aula10 where import Aula09 (Natural(..), soma, produto, paraInteiro) -- data Natural where -- S :: Natural -> Natural -- Zero :: Natural -- deriving (Show, Eq) -- -- lembrando da última aula -- exemploDoido :: Natural -> String -- exemploDoido Zero = "Hugo" -- exemploDoido (S x) = (exemploDoido x) ++ (exemploDoido x) -- -- exemploDoido é "apenas" o homomorfismo único que existe de (Natural, S, Zero) para (String, \x -> x ++ x, "Hugo") -- desafio: fatorial :: Natural -> Natural fatorial Zero = S Zero fatorial (S x) = produto (S x) (fatorial x) -- fatorial é o único homomorfismo de (Natural, S, Zero) para (Natural, ???, S Zero) -- -- -- -- -- -- data ArvBin a where Folha :: ArvBin a Raiz :: a -> ArvBin a -> ArvBin a -> ArvBin a deriving (Show, Eq) arv1 :: ArvBin Integer arv1 = Raiz 10 Folha (Raiz 4 Folha Folha) arv2 :: ArvBin Integer arv2 = Raiz 0 arv1 arv1 repeteString :: String -> Integer -> String repeteString _ 0 = "" repeteString x n = x ++ (repeteString x (n-1)) desenhaArvore :: Show a => ArvBin a -> Integer -> String desenhaArvore Folha n = (repeteString " " (5*n)) ++ "." desenhaArvore (Raiz x subarv_esq subarv_dir) n = (repeteString " " (5*n)) ++ (show x) ++ "\n" ++ (desenhaArvore subarv_esq (n+1)) ++ "\n" ++ (desenhaArvore subarv_dir (n+1)) ++ "\n" -- para casa: tornar mais bonito :) instance Functor ArvBin where fmap :: (a -> b) -> ArvBin a -> ArvBin b fmap _ Folha = Folha fmap f (Raiz r subarv_esq subarv_dir) = Raiz (f r) (fmap f subarv_esq) (fmap f subarv_dir) -- fmap tem notação infixa <$> arv3 :: ArvBin Integer arv3 = (^2) <$> arv1 -- completando um pouco o papo sobre classes de tipo instance Semigroup Natural where (<>) :: Natural -> Natural -> Natural (<>) = soma instance Monoid Natural where mempty = Zero -- foldr :: (a -> b -> b) -> b -> [a] -> b -- foldl :: (b -> a -> b) -> b -> [a] -> b meu_foldr :: (a -> b -> b) -> b -> [a] -> b meu_foldr _ val_b [] = val_b meu_foldr f val_b (cab:corpo) = f cab (meu_foldr f val_b corpo) -- meu_foldr (*) 12 [3, 5, 2] -- = 3 * (meu_foldr (*) 12 [5, 2]) -- = 3 * (5 * (meu_foldr (*) 12 [2])) -- = 3 * (5 * (2 * (meu_foldr (*) 12 []))) -- = 3 * (5 * (2 * 12)) -- = 360 meu_foldl :: (b -> a -> b) -> b -> [a] -> b meu_foldl _ val_b [] = val_b meu_foldl f val_b (cab_a:corpo) = f (meu_foldl f val_b corpo) cab_a -- versão recursiva em cauda meu_foldl_em_cauda :: (b -> a -> b) -> b -> [a] -> b meu_foldl_em_cauda _ val_b [] = val_b meu_foldl_em_cauda f val_b (cab_a:corpo) = meu_foldl_em_cauda f (f val_b cab_a) corpo -- para a próxima aula: investigar -- instance Foldable ((,) a) -- Defined in `Data.Foldable'