Funções como Valor ©André Santos e Marcelo d’Amorim.

Post on 07-Apr-2016

216 views 0 download

Transcript of Funções como Valor ©André Santos e Marcelo d’Amorim.

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