module Aula14 where import Aula13 (TalvezTurbinado(..)) import Control.Applicative -- construtor de tipos Either :: * -> * -> * -- em outras linguagens de programação, seria Tagged Union -- outra maneira de "juntar" tipos seria fazer um novo tipo no qual cada valor tenha um componente de cada um de tipos que eu especifiquei -- Listas não vão servir pois são homogêneas! type Nome = String type Idade = Integer type Vegetariano = Bool -- solução 1, "caseira" data Pessoa2 where P2 :: Nome -> Idade -> Vegetariano -> Pessoa2 deriving (Show, Eq) nome2 :: Pessoa2 -> Nome nome2 (P2 n _ _) = n -- precisaria fazer também para idade, vegetariano hugo = P2 "Hugo" 37 False tales = P2 "Tales" 25 True -- solução 2: Records data Pessoa = P { nome :: Nome, idade :: Idade, eh_vegetariano :: Vegetariano } deriving (Eq, Show) hugo2 = P "Hugo" 37 False valida_nome :: Nome -> TalvezTurbinado Nome valida_nome "Joao Paixao" = Erro ["Nao quero o Joao Paixao na festa"] valida_nome x = OK x valida_idade :: Idade -> TalvezTurbinado Idade valida_idade x | x < 18 = Erro ["nao quero problema com menor de idade"] | x > 65 = Erro ["sou etarista :("] | otherwise = OK x valida_pessoa :: Nome -> Idade -> Vegetariano -> TalvezTurbinado Pessoa valida_pessoa nome idade eh_vegetariano = P <$> (valida_nome nome) <*> (valida_idade idade) <*> (pure eh_vegetariano) -- ou então, usando liftA3 da última aula valida_pessoa2 :: Nome -> Idade -> Vegetariano -> TalvezTurbinado Pessoa valida_pessoa2 nome idade eh_vegetariano = (liftA3 P) (valida_nome nome) (valida_idade idade) (pure eh_vegetariano) -- const :: a -> b -> a -- fmap :: (a->b) -> f a -> f b -- <$ = fmap . const :: a -> f b -> f a -- u *> v = (id <$ u) <*> v -- u <* v = liftA2 const u v -- mistério! por que temos [1,2] <* [3,4] = [1,1,2,2] e [1,2] *> [3,4] = [3,4,3,4] ???? -- resolvido no quadro :) -- Alternative digit :: Integer -> [Char] -> Maybe Integer digit i (c:_) | i > 9 || i < 0 = Nothing | otherwise = if [c] == show i then Just i else Nothing binChar :: String -> Maybe Integer binChar s = digit 0 s <|> digit 1 s -- última alternativa de pessoa: tuplas data Pessoa3 = P3 (Nome, (Idade, Vegetariano)) deriving (Show, Eq) hugo3 = P3 ("Hugo", (37, True)) nome3 (P3 x) = fst x idade3 (P3 x) = (fst . snd) x eh_vegetariano3 (P3 x) = (snd . snd) x