module Aula25 where import GHC.Base -- classe de tipos Functor -- classe de tipos Applicative class Functor f => MyApplicative f where mypure :: a -> f a myapply :: f (a -> b) -> f a -> f b myliftA2 :: (a -> b -> c) -> f a -> f b -> f c -- myliftA2 fun enc_x enc_y = (mypure fun) `myapply` enc_x `myapply` enc_y myliftA2 fun enc_x enc_y = (fun <$> enc_x) `myapply` enc_y -- lei! pure fun <*> x = fun <$> x myapply = myliftA2 ($) {-# MINIMAL mypure, (myapply | myliftA2) #-} -- Exemplo data Vaca = MkVaca { nome :: String, idade :: Integer, arrobas :: Integer } deriving (Eq, Show) validaNome :: String -> Maybe String validaNome nome@('M':xs) = Just nome validaNome _ = Nothing validaIdade :: Integer -> Maybe Integer validaIdade x | x < 0 = Nothing | x > 255 = Nothing | otherwise = Just x validaArrobas :: Integer -> Maybe Integer validaArrobas x | x < 5 = Nothing | x > 1024 = Nothing | otherwise = Just x cvf:: String -> Integer -> Integer -> Maybe Vaca cvf nome idade arrobas = (liftA3 MkVaca) (validaNome nome) (validaIdade idade) (validaArrobas arrobas) data OuErro a = Erro String | OK a deriving (Eq, Show, Functor) instance Applicative OuErro where pure val_a = OK val_a (Erro erro_fun) <*> _ = Erro erro_fun _ <*> (Erro erro_val) = Erro erro_val (OK fun) <*> (OK val) = OK (fun val) validaNome' :: String -> OuErro String validaNome' nome@('M':xs) = OK nome validaNome' _ = Erro "minha vo nao gosta desse nome" validaIdade' :: Integer -> OuErro Integer validaIdade' x | x < 0 = Erro "vaca futura" | x > 255 = Erro "vaca medieval" | otherwise = OK x validaArrobas' :: Integer -> OuErro Integer validaArrobas' x | x < 5 = Erro "vaca flutua??" | x > 1024 = Erro "vaca estrela de neutron" | otherwise = OK x cvf' :: String -> Integer -> Integer -> OuErro Vaca cvf' nome idade arrobas = (liftA3 MkVaca) (validaNome' nome) (validaIdade' idade) (validaArrobas' arrobas) -- exercício: Fazer com <*> em vez de liftA3! -- exercício: Pensar na definição de liftAn com n>2