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 e words para quebrar uma linha nos brancos
  • funçoes unlines e unwords para montar o string final