{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} {-# HLINT ignore "Use camelCase" #-} {-# HLINT ignore "Redundant bracket" #-} module Aula11 where import Aula10 (ArvBin(..)) naturais :: [Integer] naturais = [0..] -- quero os naturais, mas repetindo cada elemento! -- nanaturais = [0,0,1,1,2,2,3,3,4,4,5,5..] -- para ajudar! -- quando escrevemos -- lista = [5, 7, 9] -- isso é açúcar sintático para -- lista = 5 : (7 : (9 : [])) -- usando a versão prefixa lista = (:) 5 ((:) 7 ((:) 9 [])) nova_lista = foldr (+) 3 lista -- = (+) 5 (foldr (+) 3 ((:) 7 ((:) 9 []))) -- = (+) 5 ((+) 7 (foldr (+) 3 ((:) 9 []))) -- = (+) 5 ((+) 7 ((+) 9 (foldr (+) 3 []))) -- = (+) 5 ((+) 7 ((+) 9 3)) -- talesnaturais = [[0,0],[1,1],[2,2],...] talesfun :: Integer -> [[Integer]] -> [[Integer]] talesfun n l = [n,n] : l talesnaturais :: [[Integer]] talesnaturais = foldr talesfun [] naturais nanafun :: Integer -> [Integer] -> [Integer] nanafun cab corpo = cab : (cab : corpo) nanaturais = foldr nanafun [] naturais -- nanaturais = fun 0 (fun 1 (fun 2 (fun 3 (...)))) -- [0,0,1,1,2,2,3,3,4,4,5,5..] quadrados = map (^2) naturais quadrados2 = foldr (\x l -> x^2 : l) [] naturais nomes :: ArvBin String nomes = Raiz "Hugo" (Raiz "Vitor" Folha (Raiz "Tales" Folha Folha)) Folha comprimentos :: ArvBin Int comprimentos = fmap length nomes arvore_exemplo = Raiz 8 (Raiz 7 Folha (Raiz 6 (Raiz 3 Folha Folha) Folha)) (Raiz 2 Folha Folha) instance Foldable ArvBin where foldr :: (a -> b -> b) -> b -> ArvBin a -> b foldr _ valor Folha = valor -- foldr f valor (Raiz r arv_esq arv_dir) = f r (foldr f (foldr f valor arv_esq) arv_dir) foldr f valor (Raiz r arv_esq arv_dir) = f r (foldr f (foldr f valor arv_dir) arv_esq) meu_to_list :: ArvBin a -> [a] -- meu_to_list arvore = foldr (:) [] arvore meu_to_list = foldr (:) [] -- mais natural seria mudar a assinatura do foldr class FoldableTernario t where foldrTernario :: (a -> b -> b -> b) -> b -> t a -> b instance FoldableTernario ArvBin where foldrTernario _ valor Folha = valor foldrTernario f valor (Raiz r arv_esq arv_dir) = f r (foldrTernario f valor arv_esq) (foldrTernario f valor arv_dir) in_ordem :: ArvBin a -> [a] in_ordem = foldrTernario (\raiz rec_esq rec_dir -> rec_esq ++ (raiz:rec_dir)) [] pre_ordem :: ArvBin a -> [a] pre_ordem = foldrTernario (\raiz rec_esq rec_dir -> raiz : (rec_esq ++ rec_dir)) [] ------------------------------ -- Lidar com "falhas" em algum sentido -- construtor de tipo Maybe posicao_elem :: Eq a => a -> [a] -> Maybe Integer posicao_elem x lista = posicao_elem_contador x lista 0 where posicao_elem_contador _ [] _ = Nothing posicao_elem_contador x (cab:corpo) n | x == cab = Just n | otherwise = posicao_elem_contador x corpo (n+1) quadrado_posicao_elem :: (Eq a, Num (Maybe Integer)) => a -> [a] -> Maybe Integer -- versão feia -- quadrado_posicao_elem x lista = case posicao_elem x lista of -- Nothing -> Nothing -- Just y -> Just (y^2) -- isso é exatamente o efeito do fmap do Maybe!! -- quadrado_posicao_elem x lista = fmap (^2) (posicao_elem x lista) -- ou mais sucinto ainda!! quadrado_posicao_elem = ((^2) <$>) . posicao_elem -- mas não recomendo