Aula 9
livro texto (cap 11 e 9)
Haskell online outro - so compilado
1 Maybe
data Maybe a = Nothing | Just a
Resultado de algumas funções que podem não ter resultado
:m + Data.List find (>4) [1,2,3,4,5,6,7] find (>14) [1,2,3,4,5,6,7]
import Data.Map.Strict as M let dd = M.fromList [("a",3),("b",5),("g",8)] M.lookup "b" dd M.lookup "f" dd
1.1 Funções do Maybe
2 Containers
2.1 Maybe como container
O Just a
é o "valor correto" e Nothing
é o valor errado. Eu
gostaria de poder continuar processando um Maybe enquanto o valor esta
"correto"
fmap (*5) (Just 6) fmap (*5) Nothing
2.2 Functor
Um container é um functor
se ele implementa a função fmap
:t fmap :t map
fmap é muito parecido com o map, ou na verdade, o container lista é um functor!!
O fmap aplica uma função que funciona no tipo de interno para dentro do container
Se voce esta definindo o container (tipo), vc precisa definir como o fmap funciona nele. O fmap do maybe é
instance Functor Maybe where fmap _ Nothing = Nothing fmap f (Just something) = Just (f something)
2.3 Containers com múltiplos dados
Containers contem apenas um tipo, mas podem conter múltiplos dados daquele tipo.
Uma lista [a] contem apenas dados do tipo a, mas pode conter muitos desses dados
Um dicionário Map ch v contem apenas dados do tipo ch e v, mas pode ter múltiplos dados desse tipo
o fmap, como o map, tem que aplicar a função de fora em todos os dados de dentro.
data Dic ch v = Vazio | No ch v (Dic ch v) (Dic ch v) -- dicionario implmentado como uma ABB instance Functor Dic where fmap _ Vazio = Vazio fmap f (No ch v ae ad) = No ch (f v) (fmap f ae) (fmap f ad)
2.4 applicative
Eu gostaria que:
(Just 7) + (Just 3) ==> Just 10 (Just 7) + Nothing ==> Nothing
Um container é um applicative
se ele permite jogar uma função
binaria que funciona no tipo interno para dentro do container
(+) <$> (Just 7) <*> (Just 3) (+) <$> (Just 7) <*> Nothing
o <$>
é um operador que combina uma funcao (do tipo interno do container) e um
container e retorna "algo" O <*>
é outro operador que combina o
algo com o container e retorna um container com os elementos internos
sendo o resultado da aplicação da função binaria.
A lista é também é um applicative:
(+) <$> [1,2,3,4] <*> [10,100] [11,101,12,102,13,103,14,104]
2.5 monad
Um container é uma monad
se ele implementa (entre outras coisas) a
função infixa >>= (operador de bind) que remove o dado de um container para aplica-lo em
uma função que esta esperando o tipo interno e retorna um container
com o resultado
:t (>>=) (Just 8) >>= (\x -> if odd x then Nothing else (Just (2*x+1)) )
Listas são também monadas,que são combinadas com uma operacao de concatenação
[1,2,3] >>= (\x -> if odd x then [x] else [2*x]) [1,4,3]
Monad define também a função return
que coloca um valor dentro do container
mae :: Pessoa -> Maybe Pessoa pai :: Pessoa -> Maybe Pessoa avomaternal p = ((return p) >>= mae) >>= pai avamaternal p = (return p) >>= mae >>= mae
instance Monad Maybe where Nothing >>= f = Nothing (Just x) >>= f = f x return = Just
2.6 Notação do
avomaternal p = do m <- mae p pai m
A <-
retira o valor da monada. A notação do Parece um programa "tradicional" com
o <-
como operador de atribuição
filtra f l = do x <- l if f x then [x] else [] filtra' f l = [ x | x <- l, f x] filtra odd [1,2,3,4] filtra'odd [1,2,3,4]
3 I/O
Toda operação de I/O esta dentro da monada IO
:t getLine :t putStrLn
- getLine le uma linha e retorna o string dentro da monada IO
- putStrLn recebe um string, imprime ele, e retorna uma tupla vazia dentro de IO
main = do dados <- getLine let saida = proc dados putStrLn saida
- getContents le tudo
- print converte argumentos para string e imprime
- read x
::
Int para converter um sting para inteiros - read x
::
Float para converter p/ float - funções
lines
para quebrar um string em linhas ewords
para quebrar uma linha nos brancos - funçoes
unlines
eunwords
para montar o string final