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