Aula 5

livro texto (cap 6)

haskell online

outro - so compilado

Para o compilado

main = do
       print $ sua funcao com argumentos

Currying

toda funçao em Haskell é “na verdade” uma funçao de 1 argumento (que pode retornar funções)

max 4 5

(max 4) 5

let w = max 4

w 3
w 5
:t w
w :: (Ord a, Num a) => a -> a

w precisa receber um Ord por causa do max mas também um Num por causa do 4

Prelude> :t max
max :: Ord a => a -> a -> a

Na interpretação da aula passada, max é uma função de 2 argumentos a -> a que retorna um a (e o a tem que satisfazer o Ord)

Na interpretação de currying o tipo de max é na verdade

      max :: Ord a => a -> (a -> a)

ou seja max recebe um a e retorna uma função que esta esperando um a para retornar um a (que é a função armazenada em w)

Veja que nos podemos escrver a função w como

w x = max 4 x

w = max 4

essa segunda versão/notação é chamada de point-free style

Funções infixas (+, etc) para funções unárias:

(8+)
:t (+8)
f1 = (<5)
:t f1

f2 = (5>)
:t f2

maiuscula = (`elem` ['A'..'Z'])

(<5) (expressoes infixas incompletas) são chamados sessions

funções que recebem funções como argumento

aplica2 f x = f (f x)
:t aplica2
aplica2 :: (t -> t) -> t -> t
zipWith' f [] _ = []
zipWith' f _ [] = []
zipWith' f (a:as) (b:bs) = f a b : (zipWith' f as bs)

zipWith' (+) [1..5] [1000..1004]
flip' f = g 
    where g x y = f y x 

zipWith' (flip' div) [2,2,2,1] [10,8,4,0]

flip e zipWith já estão definidas

o $

aplica2 f x = f (f x)

aplica2 f x = f $ f x
:t aplica2

o $ é um abre parênteses com o fecha parênteses implicito no fim do comando.

o $ é um pipe f (g (h x)) = f $ g $ h x

map e filter

map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (a:as) = f a : (map f as)

map (5-) [10,8..0]
filter :: (a -> Bool) -> [a] -> [a]  
filter _ [] = []  
filter p (x:xs)   
    | p x       = x : (filter p xs)  
    | otherwise = filter p xs  

impar x = x `mod` 2 == 1

filter impar [1,5,4,3,6,7,8]

map e filter ja estao definidas

Num certo sentido, o list comprehension combina o map e o filter

map f $ filter p lista 
[ f x | x <- lista, p x]

funções anônimas

Cria funções sem nomes


\ argumentos -> corpo

filter (\ x -> x `mod` 2 == 1) [1,5,4,3,6,7,8]

zipWith (\a b -> if a>b then a+3 else b-1) [1,2,3,4] [5,4,3,2]

fold

foldr

foldr é a recursao tradicional (o resultado vem da direita - fim da lista)

soma [] = 0
soma (x:xs) = x + (soma xs)

-- foldr combina valor-inicial lista
foldr _ init [] = init
foldr f init (x:xs) = f x (foldr f init xs)

soma l = foldr (+) 0 l

soma = foldr (+) 0


:t foldr

veja o tipo da funçao de combinação

foldl

foldl é a recursao com acumulador, que o resultado vem da esquerda - do começo da lista

-- foldl combina valor-inicial lista

somaacc acc [] = acc
somaacc acc (x:cs) = somaacc (acc+x) xs


foldl _ acc [] = acc
foldl f acc (x:xs) = foldl f  (f acc x) xs


somaacc l = foldl (+) 0 l

somaacc = foldl (+) 0

:t foldl

veja o tipo da funçao de combinação

foldr1 e foldl1

foldr1 é o foldr onde o valor inicial é o ultimo elemento

foldl1 é o foldl onde o valor inicial do acumulador é o primeiro elemento

minimo = foldl1 (\a b -> if a<b then a else b) 
minimo = foldl1 min

produto = foldr1 (*)

produtoescalar l1 l2 = foldr1 (+) $ zipWith (*) l1 l2

produtoescalar  = foldr1 (+) $ zipWith (*) 

Exercícios

(map, filter, fold)

1  2  3
4  5  6 
7  8  9
0  0 -1

[[1,2,3],[4,5,6],[7,8,9],[0,0,-1]]

implemente transposta que transpoe uma matrix