Aula 5

livro texto (cap 6)

Haskell online outro - so compilado

Para o compilado

main = do
       print $ ...

1 Teste

Implemente a função:

posicoes:: (Eq a, Num b) => a -> [a] -> [b]

que dado um item e uma lista, retorna os posições do item na lista, onde o primeiro elemento da lista esta na posição 0. Se o item não esta na lista, retorna a lista vazia

posicoes 'a' "asdfgasdfaaas"  
=> [0,5,9,10,11]

posicoes 'g' "asdfgasdfaaas"  
=> [4]
posicoes 'z' "asdfgasdfaaas"  
=> []

2 Currying

toda funçao em Haskell é "na verdade" uma funçao de 1 argumento (que pode retornar funçoes)

max 4 5

(max 4) 5

let a = max 4

a 3
a 5
:t a

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

a x = max 4 x

a = max 4

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

Funcoes infixas (+, etc)

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

f2 = (5>)
:t f2

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

3 funcoes que recebem funções como argumento

aplica2 f x = f (f x)

aplica2' f x = f $ f x
:t aplica2

zipWith' f [] _ = []
zipWith' f _ [] = []
zipWith' f (a:as) (b:bs) = f a b : (zipWith' f as bs)

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

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

flip e zipWith já estão definidas

4 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 l 
[ f x | x <- lista, p x]

5 funcoes anonimas

Cria funcoes sem nomes

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]

6 fold

6.1 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
 

6.2 foldl

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

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

6.3 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 (*)

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

prodescalar  = foldr1 (+) $ zipWith (*) 

7 Exercicios

  • reimplemente os exercicios da aula 1 e 2 usando as funcoes de alto nivel

(map, filter, fold)

  • uma matrix é implementada como uma lista de linhas (que são listas)
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

  • implemente matmul que dado duas matrizes de formatos apropriados multiplica-as. (*)