View
214
Download
0
Category
Preview:
Citation preview
Funções como Valor
©André Santos e Marcelo d’Amorim
FUNÇÕES DE ALTA ORDEM
©André Santos e Marcelo d’Amorim
Funções de alta ordem
• Funções como argumentos ou resultado de outras funções
©André Santos e Marcelo d’Amorim
Por que funções de alta ordem?
• Modularidade!– Separa conceitos– Facilita reuso com composição de funções
©André Santos e Marcelo d’Amorim
Exemplo: análise de vendas-- função de alta ordemtotal :: (Int->Int)-> Int -> Inttotal f 0 = f 0total f n = total f (n-1) + f n-- instanciaçõestotalSales n = total sales nsumSquares :: Int -> IntsumSquares n = total sq n
©André Santos e Marcelo d’Amorim
Outros exemplos
maxFun :: (Int -> Int) -> Int -> IntmaxFun f 0 = f 0maxFun f n = maxi (maxFun f (n-1)) (f n)
zeroInRange :: (Int -> Int) -> Int -> BoolzeroInRange f 0 = (f 0 == 0)zeroInRange f n = zeroInRange f (n-1) || (f n == 0)
©André Santos e Marcelo d’Amorim
Exercício
• Use a função maxFun e sales para implementar uma que retorna o maior número de vendas de uma semana de 0 a n semanas
maxSales :: Int -> Int
• Dada uma função, verificar se ela é crescente em um intervalo de 0 a n
isCrescent :: (Int -> Int) -> Int -> Bool
©André Santos e Marcelo d’Amorim
POLIMORFISMO
©André Santos e Marcelo d’Amorim
Polimorfismo
• Função possui um tipo genérico; pode ser usada em várias situações
• Requer variáveis de tipos• Exemplo de tipo polimórfico:
©André Santos e Marcelo d’Amorim
(t,u) -> u
Tipo função que recebe um par e retorna um valor com mesmo tipo do segundo elemento do par.
Exemplo
©André Santos e Marcelo d’Amorim
snd :: (t,u) -> usnd (_,y) = y
fst:: (t,u) -> tfst(x,_) = x
head:: [a] -> ahead a:_ = a
tail:: [a] -> atail _:x = x
Qual o tipo de zip?
zip (a:as) (b:bs) = (a,b):zip as bs zip _ _ = []
©André Santos e Marcelo d’Amorim
Qual o tipo de zip?
zip (a:as) (b:bs) = (a,b):zip as bs zip _ _ = []
©André Santos e Marcelo d’Amorim
zip :: [t] -> [u] -> [(t,u)]
Polimorfismo
length [] = 0length (a:as) = 1 + length as
reverse [] = []reverse (a:as) = reverse as ++ [a]
id x = x
• Funções com várias instâncias de tipo©André Santos e Marcelo d’Amorim
Polimorfismo
replicate 0 ch = []replicate n ch = ch : replicate (n-1) ch
• Hugs/Haskell: inferência de tipos
©André Santos e Marcelo d’Amorim
Main> :type replicate
Int -> a -> [a]
Main>
Exercícios
• Defina as seguintes funções que coletam (take) ou descartam (drop) n elementos na cabeça de uma lista
take, drop :: Int -> [t] -> [t]
©André Santos e Marcelo d’Amorim
Exercícios
• Defina a função takeWhile (resp., dropWhile) que coleta (resp., descarta) elementos enquanto uma condição de parada (função de entrada) é satisfeita:
takeWhile, dropWhile :: (t -> Bool) -> [t] -> [t]
©André Santos e Marcelo d’Amorim
Exercícios
• Baseado nas definições de takeWhile e dropWhile (ver aula anterior) defina as seguintes funções:
getWord :: String -> StringdropWord :: String -> StringdropSpace :: String -> String
©André Santos e Marcelo d’Amorim
OVERLOADING
©André Santos e Marcelo d’Amorim
Tipo especial de polimorfismo
• Definição com mesmo nome
• Objetivo é o mesmo. Permitir que o mesmo nome seja usado em contextos diferentes
©André Santos e Marcelo d’Amorim
(==) :: Int -> Int -> Bool(==) :: Bool -> Bool -> Bool
EXPRESSÃO LAMBDA
©André Santos e Marcelo d’Amorim
Retornando uma função
• Vimos como escrever uma função que recebe outra como argumento.
• Ainda não aprendemos como escrever uma que retorna.
©André Santos e Marcelo d’Amorim
Exemplo
• Função que recebe um inteiro e retorna outra que recebe um segundo inteiro e soma o primeiro.
©André Santos e Marcelo d’Amorim
addNum :: Int -> (Int -> Int)addNum n = addN where addN m = n + maddFour = addNum 4
Expressão Lambda (\ e ->)
©André Santos e Marcelo d’Amorim
addNum :: Int -> (Int -> Int)addNum n = (\m -> n + m)
• Outra definição para addNum
comp2 :: (t -> u) -> (u -> u -> v) -> (t -> t -> v)
comp2 f g = (\x y -> g (f x) (f y))
\x y -> g (f x) (f y)
y
f
f g
g (f x) (f y)
comp2x
Exercício
• Dada uma função f do tipo t -> u -> v, defina uma expressão da forma
(\... -> ...) para uma função do tipo u -> t -> v
que se comporta como f mas recebe seus argumentos na ordem inversa
CURRIFICAÇÃO E APLICAÇÃO PARCIAL
©André Santos e Marcelo d’Amorim
Currificação
• Toda função em Haskell recebe exatamente 1 argumento!
• Quando mais de um é necessário, usa-se currying– Transfere para outra função o resto da
computação
©André Santos e Marcelo d’Amorim
Exemplo
©André Santos e Marcelo d’Amorim
multiply :: Int -> Int -> Intmultiply x y = x * y
Exemplo
©André Santos e Marcelo d’Amorim
multiply :: Int -> (Int -> Int)multiply x y = x * y
-> associa a direita!
Resto do cálculo
Avaliação Parcial
©André Santos e Marcelo d’Amorim
multiply 2(multiply 2) 5
Quais os tipos?
Avaliação Parcial
©André Santos e Marcelo d’Amorim
multiply 2 :: Int -> Int(multiply 2) 5 :: Int
Avaliação Parcial
©André Santos e Marcelo d’Amorim
Main> multiply 2\m -> 2 * m Main>(multiply 2) 510
Hugs não consegue apresentar esta valor
Associatividade
• f a b = (f a) b• t -> u -> v = t -> (u -> v)
Funções Uncurried• Deseja-se obrigar passar todos argumentos simultaneamente• Usa-se produto cartesiano (tuplas)
©André Santos e Marcelo d’Amorim
multiplyUC :: (Int,Int) -> IntmultiplyUC (x,y) = x * y
Exercício
©André Santos e Marcelo d’Amorim
uncurry :: (a -> b -> c) -> ((a,b) -> c)
• Defina a função uncurry, que transforma uma versão curried em uncurried.
Exercício
©André Santos e Marcelo d’Amorim
uncurry :: (a -> b -> c) -> (a,b) -> cuncurry f (x,y) = f x y
Definida em Prelude.hs
Recommended