Aula 21

haskell interativo

haskell compilado - rextester

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 o do 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

Author: Jacques Wainer

Created: 2018-05-21 Mon 15:19

Validate