Aula 21
1 Lei de benford
funcao que recebe 1 string e retorna a proporcão de cada um dos digitos 0 a 9 no texto na forma de uma lista de duplas [('0',0.2),('1',0.31),...]
- Lista com proporcoes de cada digito = 3 pontos
- lista com quantidade = 2 pontos
Util: Data.Char, Data.List ou Data.Map.Strict
A funcao pode ser linear no tamanho do string ou n log(n).
2 Containers in Haskell
Containers - tipos de dados que contem dados de outro tipo (interno)
- listas!!
- Maybe a
2.1 Functor
Um container é um Functor, se alguem/voce define a funcao
fmap :: (a -> b) -> C a -> C b
que mapeia/aplica uma funcao dos tipos internos dentro do container c
fmap é como o map (para o container lista!)
fmap (3+) (Just 5) Just 8
instance Functor Maybe where fmap f (Just x) = Just (f x) fmap f Nothing = Nothing
2.2 Applicative
um container é Applicative se alguem/voce define as funcoes/operadores
pure :: a -> c a (<*>) :: c (a -> b) -> c a -> c b
pure
coloca um dado no container
<*>
aplica uma funcao dentro do container c (a->b)
num dado no container c a
e <?>
coloca uma funçao dentro do container
f <?> x = (pure f) <*> x
assim em Applicative voce pode fazer funcoes binarias funcionarem dentro do container.
(*) <$> Just 4 <*> Just 3 Just 12 (*) <$> [4,5] <*> [2,3,10] [8,12,40,10,15,50]
Alguem definiu que em listas todas as possiveis combinacoes de operados sao computadas
2.3 Monads
um container é Monad se alguem definir as funcoes/operacoes
return :: a -> c a (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b
return
(como o pure
) coloca um dado no container
(>>=) recebe um dado no container e uma funcao que espera o dado interno e remove o dado do container para usa-lo na funcao!
(>>)
tem uma nocao de fazer algo depois do outro: a funcao esta esperando um m a e um m b e retorna o m b (
Monad implementam a nocao de "tirar um dado do container" que pode nao ser possivel para todos os containetrs (lista por exemplo - como tirar um dado de uma lista que tem mais de um elemento!!)
instance Monad Maybe where return x = Just x Nothing >>= f = Nothing Just x >>= f = f x
2.4 Funcoes puras
Haskell espera que todas as funcoes sejam puras - para a mesma entrada a saida é sempre a mesma.
- ok ja que nao existem variavies globais.
- mas nao é verdade para leitura, nao é verdade para geradores de numeros aleatorios, pode nao ser verdade para saida (espaço em disco).
Funcoes não puras tem que estar dentro de containers (Monad ?)
2.5 IO
IO é um Monad
main :: IO () putStrLn :: String -> IO () getLine :: IO String
Dentro do do
<-
: retira algo de dentro da Monad (é um pouco mais complicado pois Monad nao implementa o "tirar de dentro", so o equivalente no operador (=>>)- uma linha abaixo da outra é a operacao
(>>)
main = do putStrLn "Hello, what's your name?" name <- getLine
name
é do tipo String (fora do IO)PutStrLn
retorna IO () que é o que odo
retorna
map print [1,2,3]
nao funciona
*Main> :t map map :: (a -> b) -> [a] -> [b] *Main> :t print print :: Show a => a -> IO ()
daria um [IO ()]
que nao é o tipo certo
O certo é usar mapM
( o equvalente de um map para Monads)
*Main> :t mapM mapM :: (Monad m, Traversable t) => (a -> m b) -> t a -> m (t b) *Main> mapM print [1,2,3] 1 2 3 [(),(),()] *Main> mapM_ print [1,2,3] 1 2 3
Capitulos 12 e 13 sao sobre como usar monads para resolver problemas como
- programas com numeros aleatorios
- programas com logging
- programas com estado
- estruturas de dados funcionais
3 Futuro
proximo livro de haskell Real World Haskell
num futuro proximo voce esta pensando assim: questao no stack overflow e outra