• Em uma linguagem funcional, uma função é um valor como qualquer outro
• Isso quer dizer que funções podem ser passadas como parâmetros para
outras funções e retornadas de outras funções
• Passagem e retorno de funções nos dá uma ferramenta poderosa para
• Funções que recebem ou retornam outras funções são chamadas de funções
• Seja uma função que calcula a soma dos inteiros entre a e b:
• def somaInt(a: Int, b: Int): Int = if (a > b) 0 else a +
• Seja agora uma função que calcula a soma dos quadrados dos inteiros entre a
• def somaQuad(a: Int, b: Int): Int = if (a > b) 0 else
• Seja agora uma função que soma os fatoriais dos inteiros entre a e b:
• def somaFat(a: Int, b: Int): Int = if (a > b) 0 else
• Todas essas funções são muito parecidas! Elas são casos especiais de:
• def soma(f: Int => Int, a: Int, b: Int): Int = if (a > b) 0
• def somaInt(a: Int, b: Int) = soma(id, a, b)
• def somaQuad(a: Int, b: Int) = soma(quadrado, a, b)
• def somaFat(a: Int, b: Int) = soma(fat, a, b)
• Um tipo A => B é o tipo de uma função que recebe um argumento do tipo A e
retorna um resultado de tipo B, logo Int => Int é uma função que recebe um inteiro e retorna um inteiro
• Passar funções como parâmetros leva à criação de muitas funções pequenas
• Às vezes queremos denotar uma função sem precisar dar um nome para ela
• Do mesmo jeito que usamos literais como 2, 3, “foo” e expressões como
• Scala fornece uma sintaxe de funções anônimas para isso
• Exemplo: uma função que eleva seu argumento ao quadrado:
• O termo (x: Int) dá a lista de parâmetros da função anônima, e x * x é o
• Em algumas ocasiões o tipo do parâmetro pode ser omitido!
• Funções anônimas com vários parâmetros são possíveis:
• Podemos definir as funções de somatório usando soma e funções anônimas:
• def somaInt(a: Int, b: Int) = soma(x => x, a, b)
• def somaQuad(a: Int, b: Int) = soma(x => x * x, a, b)
• def somaFat(a: Int, b: Int) = soma(fat, a, b)
• Repare que não precisamos dizer o tipo do parâmetro x das funções
anônimas, pois o compilador sabe que soma precisa de uma função Int => Int
• Se não precisamos dizer o tipo, e a função anônima tem apenas um
parâmetro, então podemos omitir os parênteses também
• Escreva uma função produto que calcula o produto dos valores de uma
função de inteiros para inteiros em determinado intervalo
• Escreva a função que calcula o fatorial em termos de produto
• É possível generalizar tanto soma quanto produto?
• Relembrem as funções de somatório:
• def somaInt(a: Int, b: Int) = soma(x => x, a, b)
• def somaQuad(a: Int, b: Int) = soma(x => x * x, a, b)
• def somaFat(a: Int, b: Int) = soma(fat, a, b)
• Reparem que os parâmetros a e b são passados sem mudanças para a função
• Podemos nos livrar deles fazendo soma retornar uma função!
def soma(f: Int => Int): (Int, Int) => Int = {
• Ela agora é uma função que retorna outra função: repare no seu tipo de
• Agora podemos redefinir os somatórios como:
• def somaInt(a: Int, b: Int) = soma(x => x)
• def somaQuad(a: Int, b: Int) = soma(x => x * x)
• def somaFat(a: Int, b: Int) = soma(fat)
• Podemos até usar soma diretamente: soma(quadrado)(1, 10)
• Funções retornando funções são tão comuns em programação funcional que
def soma(f: Int => Int)(a: Int, b: Int): Int =
if (a > b) 0 else f(a) + soma(f)(a + 1, b)
• Esse estilo de uso de funções é chamado de currying, é a maneira normal de
definir funções com múltiplos argumentos em algumas linguagens funcionais
• Existem linguagens funcionais em que todas as funções recebem apenas um
• O tipo de soma é (Int => Int) => (Int, Int) => Int
• Em matemática, x é um ponto fixo da função f se f(x) = x
• Para algumas funções, uma maneira de achar um ponto fixo é começando
com uma estimativa e repetidamente aplicando f:
• x, f(x), f(f(x)), f(f(f(x))), f(f(f(f(x)))), .
• Até que a variação entre um valor e o próximo seja pequena o suficiente
• A definição do slide anterior nos dá uma receita para escrever uma função
Scala que acha um ponto fixo de outra função:
def pontoFixo(f: Double => Double)(est: Double): Double = {
def suficiente(est1: Double, est2: Double) =
• Vamos pensar na especificação da função raiz:
• raiz(x) = um número y tal que y * y = x
• Dividindo ambos os lados da equação y * y = x por y:
• raiz(x) = um número y tal que y = x / y
• Ou seja uma raiz quadrada de x é um ponto fixo para a função f(y) = x / y!
• def raiz(x: Double) = pontoFixo(y => x / y)(1.0)
• def raiz(x: Double) = pontoFixo(y => x / y)(1.0)
• Vamos debugar com println e ver o que está acontecendo
• A raiz(x) é um número y tal que y = x / y
• Se adicionarmos y a ambos os lados da equação e simplificarmos temos:
• raiz(x) = um número y tal que y = (y + x / y)/2
• O que acontece se tentamos achar o ponto fixo dessa segunda função em y?
• Uma terceira maneira de achar uma raiz quadrada de um número x é achando
uma solução da equação y2 - x = 0
• Um método numérico de achar raízes de funções é o método de Newton, que
consiste em, para uma equação dada por g(x) = 0, achar o ponto fixo da função:
• f(x) = x - g(x)/g’(x), onde g’(x) é a primeira derivada de g(x)
• Já temos quase todas as ferramentas, só precisamos da derivada! Mas isso é
• g’(x) = (g(x + dx) - g(x)) / dx, para um dx pequeno o bastante
Hugo Pena Brandão e Carla Patricia Bahry Gestão por competências: métodos e técnicas para mapeamento de competências Hugo Pena Brandão e Carla Patricia Bahry Introdução A gestão por competências tem sido apontada como modelo gerencialalternativo aos instrumentos tradicionalmente utilizados pelas organizações. Baseando-se no pressuposto de que o domínio de certos
Tableau des réductions et restrictions. Valables les 11,12 13 octobre 2011 exlusivement Réduction sur forfait Avantages Compagnies Les marques concernées 5% de Réduction sur croisière Exceptions (aérien supplémentaires Réservation participantes si différentes en Port Port Hors Taxes éventuels Aériennes) Ces réductions et avantages so