Vous êtes sur la page 1sur 29

Lambda Clculo e Programao Funcional

Programao Funcional Bacharelado em Sistemas de Informao Maio - 2009

Alonzo Church (19031995)


Professor em Princeton, EUA (19291967) e UCLA (19671990) Inventou um sistema formal, chamado -calculus (Lambda Clculo) , e definiu a noo de funo computvel utilizando este sistema. O Lambda Clculo pode ser chamado a menor linguagem de programao universal do mundo. As linguagens de programao funcionais, como Lisp, Miranda, ML, Haskell so baseadas no Lambda Clculo.

Lambda Clculo
O lambda clculo pode ser visto como uma linguagem de programao abstrata em que funes podem ser combinadas para formar outras funes, de uma forma pura. O lambda clculo trata funes como cidados de primeira classe, isto , entidades que podem, como um dado qualquer, ser utilizadas como argumentos e retornadas como valores de outras funes.

Sintaxe
Uma expresso simples do lambda clculo: (+ 4 5) Todas as aplicaes de funes no lambda clculo so escritas no formato prefixo. Avaliando a expresso: (+ 4 5) = 9 A avaliao da expresso procede por reduo: (+ (* 5 6)(* 4 3)) (+ 30 (* 4 3)) (+ 30 12) 42

Sintaxe
Uma abstrao lambda um tipo de expresso que denota uma funo: (x. + x 1) O determina que existe uma funo, e imediatamente seguido por uma varivel, denominada parmetro formal da funo. ( x . + x 1)
A funo de x que incrementa x de 1

Sintaxe
Uma expresso lambda deve ter a forma:
<exp> ::= <constante> | <variavel> | <exp> <exp> | .<variavel> <exp>

Os parnteses podem ser utilizados nas expresses para prevenir ambiguidades.

Exemplos
(x. x) y (x. f x) xy (x. x) (x. x) (x. x y) z (x y. x) t f (x y z. z x y) a b (x y. x) (f g. f g) (x. x) (x. x) z (x y. x y) y (x y. x y) (x. x) (x. x) (x y. x y) ((x. x) (x. x))

Anlise de Expresses Lambda


A expresso Lambda se estende para a direita

f. x y xyz f g. x

f.(x y) (x y) z f . g. x

A aplicao associativa esquerda

Mltiplos lambdas podem ser omitidos

Variveis Livres e Ligadas


A varivel x ligada por na expresso: x.e Caso a varivel no seja ligada, ento considerada livre. As variveis livres de um termo so definidas como:
FV(x) FV(e1 e2) FV( x . e) = = = {x} FV(e1) FV(e2) FV(e) - { x }

Para a expresso abaixo, y ligada e x uma varivel livre.


y.xy

Variveis Livres e Ligadas


( x. + x y) 4

Para avaliar completamente a expresso, necessrio conhecer o valor global de y. Para x, a varivel local e pertence funo. Exemplos:
x. + (( y. + y z) 7) x + x (( x. + x 1) 4)
// z livre // o primeiro x livre

Reduo
A aplicao de um argumento uma abstrao lambda implica na substituio das ocorrncias das variveis correspondentes ao argumento:
( x. + x 1) 4

+ 4 1

Esta operao denominada -reduo. Funes tambm podem ser passadas como argumento:
( f. f 3) ( x. + x 1)

( x. + x 1) 3 + 3 1 4

-reduo
( x. y. + (- x 1)) x 3) 9 ( x. + (- x 1)) 9 3 + (- 9 1) 3 + 8 3 11 ( x. y. + x (( x.- x 3) y)) 5 6

??

Converso
Considere as duas abstraes lambda:
( x. + x 1) ( y. + y 1) Claramente as duas abstraes acima so equivalentes e uma -converso nos permite mudar o nome do parmetro formal de uma abstrao lambda. Ento: ( x. + x 1)

( y. + y 1)

Converso
Considere as duas expresses:
( x. + 1 x) (+ 1) Ambas tem o mesmo comportamento quando aplicadas argumento: adicionam 1 ao argumento. Uma reduo uma regra expressando tal equivalncia: ( x. + 1 x )

(+ 1)

reduo (Equivalncia)
( x. + 1 x) (+ 1)

Em Haskell:
Main> (\x (+) 1 x) 4 5 Main> ( (+) 1) 4 5

Resumo
converso (renomeao) reduo (aplicao) converso
x.e y. e Quando y no uma varivel livre em e. Operaes de renomeao e substituio. Elimina uma abstrao mais complexa.

( x . e1) e2

[ e2/x ] e1

x.ex e

Exemplos de funes
Exemplo: rea de um crculo F * r2, r N Q x * x, x N H=FQ H(r) = 3,14 * Q(r) Abstrao Lambda:
Em Haskell:

(funo composta) (Fortran)

y. * y * y
Main> (\y -> pi * y * y) 3 28.2743338823081

Exemplos de funes
int f(x) { return x+2; } f(5);
(f. f(5)) (x. x+2) Bloco principal Funo declarada

Exemplos de funes
Dada uma funo f, defina uma expresso f f:

f. x. f (f x)
Aplicao para f(x) = x+1:

(f. x. f (f x)) (y. y+1) = x. (y. y+1) ((y. y+1) x) = x. (y. y+1) (x+1) = x. (x+1)+1

Tuplas como funes


Em Haskell:
t f pair first second = = = = = \x \x \x \p \p -> -> -> -> -> \y -> x \y -> y \y -> \z -> z x y p t p f

Main> first (pair 1 2) 1 Main> first (second (pair 1 (pair 2 3))) 2

Exerccios
1. Calcular a mdia das notas dos alunos de um curso:
type Aluno = (Int, String, Float) -- N Aluno, Nome, Nota type Curso = [Aluno] listaAlunos :: Curso listaAlunos = [(1234, "Jose Azevedo", 13.2), (2345, "Carlos Silva", 9.7), (3456, "Rosa Mota", 17.9)] media :: Curso->Float media l = (/) (sum (map (\(_,_,n)->n) l)) (fromIntegral (length l))

Exerccios
Main> media listaAlunos 13.6 Funes utilizadas: fromIntegral : funo que transforma o argumento em um nmero da classe Fractional Exemplo: divisao a b = (fromIntegral a) / (fromIntegral b) map : funo que aplica uma funo a todos os elementos de uma lista. Exemplo: Main> dobro 3 9

Exerccios
Main> map dobro [1,2,3] [1,4,9] Main> map (\(_,n) -> n) [(1,2),(3,4)] [2,4] sum : funo que soma os elementos de uma lista. Main> sum [1,2,3] 6 Main> sum ['a','b','c'] ERROR - Cannot infer instance *** Instance : Num Char *** Expression : sum ['a','b','c'] Main> sum [1.2,3.3] 4.5

Exerccios
2. Implementar uma funo que calcula o sucessor de um nmero inteiro usando expresso lambda (x. x+1). Em seguida, definir uma funo duasVezes para aplicar uma funo nela mesma. Finalmente, construir uma funo para mapear a aplicao de duasVezes sobre uma lista de inteiros.
sucessor::(Int -> Int) sucessor = \x -> x + 1 Main> 2 Main> 6 Main> ERROR sucessor 1 sucessor 5 sucessor 'a' - Type error in application

Exerccios
Funo duasVezes para aplicar uma funo nela mesma:
sucessor::(Int -> Int) sucessor = \x -> x + 1 duasVezes :: (a->a) ->a ->a duasVezes f x = f (f x)
Main> 7 Main> 102 Main> ERROR

duasVezes sucessor 5 duasVezes sucessor 100 duasVezes sucessor 5.6


- Cannot infer instance

Exerccios
Funo mapear para aplicar uma funo uma lista de Valores (sem usar a funo map)
sucessor::(Int -> Int) sucessor = \x -> x + 1 duasVezes :: (a->a) ->a ->a duasVezes f x = f (f x) mapear::(a->b)->[a]->[b] mapear f [] = [] mapear f (x:xs) = (f x): mapear f xs

Exerccios
Main> mapear sucessor [1,3,5] [2,4,6] Main> mapear (duasVezes sucessor) [1,3,5] [3,5,7] Main> mapear (duasVezes (+ 1)) [1,3,5] [3,5,7] Main> mapear (duasVezes (\x -> x * x)) [3,4,5] [81,256,625] Main> mapear (\y -> y ++ y) ["na","ta","la"] ["nana","tata","lala"] Main> mapear (duasVezes (\y -> y ++ y)) ["na","ta","la"] ["nananana","tatatata","lalalala"]

Exerccios
3. Dados um elemento e uma lista, intercale o elemento na lista, em todas as posies.
intercala :: a -> [a] -> [[a]] intercala x [] = [[x]] intercala x (l:ls) = [x:l:ls] ++ map (l:) (intercala x ls) Main> intercala 1 [2,3] [[1,2,3],[2,1,3],[2,3,1]]

Exerccios
4. Reduza as expresses avaliando-as e escreva o cdigo correspondente em Haskell, testando no ambiente Hugs.
1) ( x.2*x + 1) 3 2) ( xy.x+y) 5 7 3) ( yx.x+y) 5 7 4) ( xy.x-y) (z.z/2) 5) ( x.xx) ( y.y) 6) ( x. y. x + (( x.8) - y)) 5 6 7) ( x. y. x y) 9 4

Vous aimerez peut-être aussi