{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} {-# HLINT ignore "Use camelCase" #-} module Aula12 where 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 => a -> [a] -> Maybe Integer -- quadrado_posicao_elem x lista = fmap (^2) (posicao_elem x lista) -- quadrado_posicao_elem x = ((^2) <$>) . (posicao_elem x) quadrado_posicao_elem = (((^2) <$>) .) . posicao_elem -- posicao_elem :: a -> ([a] -> Maybe Integer) -- (^2) :: Num a => a -> a -- (<$>) :: Functor f => (a -> b) -> f a -> f b -- ((^2) <$>) :: (Num a, Functor f) => f a -> f a composta_binaria :: (c -> d) -> (a -> b -> c) -> a -> b -> d -- composta_binaria f_depois f_antes x y = f_depois (f_antes x y) -- composta_binaria f_depois f_antes x = f_depois . (f_antes x) -- composta_binaria f_depois f_antes = (f_depois .) . f_antes composta_binaria f_depois = ((f_depois .) .) -- DESAFIO: como "tirar" esse f_depois também??? quadrado_posicao_elem' :: Eq a => a -> [a] -> Maybe Integer quadrado_posicao_elem' = composta_binaria ((^2) <$>) posicao_elem data Talvez a where Nada :: Talvez a -- Nada é de QUALQUER tipo Talvez bla DeFato :: a -> Talvez a deriving (Eq, Show, Ord, Read) instance Functor Talvez where fmap :: (a -> b) -> Talvez a -> Talvez b fmap _ Nada = Nada fmap fun (DeFato x) = DeFato (fun x) -- outro tipo de dados bastante usado é o Either data XOR a b where Esq :: a -> XOR a b Dir :: b -> XOR a b deriving (Eq, Show, Ord, Read) instance Functor (XOR a) where fmap :: (b -> c) -> XOR a b -> XOR a c fmap _ (Esq val_a) = Esq val_a fmap fun (Dir val_b) = Dir (fun val_b) data Erro = DeuRuim | NaoEhNumero | DivisaoPorZero deriving (Eq, Show) posicao_elem_mais_informativo :: Eq a => a -> [a] -> Either Erro Integer posicao_elem_mais_informativo x lista = posicao_elem_mais_informativo_contador x lista 0 where posicao_elem_mais_informativo_contador _ [] _ = Left DeuRuim posicao_elem_mais_informativo_contador x (cab:corpo) n | x == cab = Right n | otherwise = posicao_elem_mais_informativo_contador x corpo (n+1) -- relembrando aula passada data Natural where Zero :: Natural S :: Natural -> Natural deriving (Eq, Show) soma x Zero = x soma x (S y) = S (soma x y) prod _ Zero = Zero prod x (S y) = soma x (prod x y) potn _ Zero = S Zero potn x (S y) = prod x (potn x y) -- é o padrão do fold!! -- instance Foldable Natural where -- não funciona porque Natural é * e Foldable é só para * -> * class FoldableTipo t where foldT :: (a -> a) -> a -> t -> a foldNatural :: (a -> a) -> a -> Natural -> a foldNatural _ caso_base Zero = caso_base foldNatural fun caso_base (S x) = fun (foldNatural fun caso_base x) instance FoldableTipo Natural where foldT = foldNatural somaFold = foldT S prodFold x = foldT (somaFold x) Zero potnFold x = foldT (prodFold x) (S Zero) torreFold x = foldT (potnFold x) (S Zero)