5.5 Expressão Lambda

Nas linguagens de programação funcionais podemos definir funções de várias formas. Um dos jeitos é definirmos expressões e em seguida nomeá-las, que é o jeito que fizemos até então, mas um outro jeito é criar uma expressão lambda.

Expressões lambdas são basicamente funções anônimas que criamos porque precisamos de uma função apenas uma vez. Geralmente, uma função lambda é escrita com o único propósito de passá-la para uma função de ordem superior .

Para construir uma expressão lambda em Haskell, nós escrevemos o sinal de barra (\, que remete à letra grega lambda: ) seguido dos parâmetros separados entre espaços. Após estes, escrevemos -> e então o corpo da função.

Um bom exemplo de aplicação de expressão lambda é o Exemplo 40, onde definimos a função square apenas para com o intuito passá-la como parâmetro de map. Utilizando expressão lambda, o código fica bem mais simples, como demonstrado o Exemplo 44:

Exemplo 44:

map (\x -> x * x) [1,2,3,4,5]

Outro exemplo da utilidade das funções lambdas é usá-las para criar funções que serão retornadas por alguma função de ordem superior. Por exemplo, imaginemos um cenário onde precisamos definir algumas funções de segundo grau, conforme o Exemplo 45:

Exemplo 45:

f1 x = 3 (x x) + 4 * x + 1

f2 x = 6 (x x) + 7 * x + 5

f3 x = 5 (x x) + 3 * x + 2

É fácil perceber que há um padrão na criação das funções uma vez que todas elas são do mesmo tipo (funções de segundo grau), e que há também uma repetição de código, o que certamente facilita a criação de erros e dificulta a manutenção. Poderíamos resolver isso construindo uma função genérica que cria nossas funções de segundo grau, uma vez que indiquemos a ela quais são as constantes da função (no caso de f1 seriam 3,4,1). Vamos definir essa função como quadraticFunction, como mostra o Exemplo 46:

Exemplo 46:

quadraticFunction a b c = \x -> a (x x) + b * x + c

Com isso, podemos definir facilmente nossas funções de segundo grau, como ilustrado no Exemplo 47:

Exemplo 47:

nf1 = quadraticFunction 3 4 1

nf2 = quadraticFunction 6 7 5

nf3 = quadraticFunction 5 3 2

Vale ressaltar que f1 e nf1 possuem exatamente a mesma definição: ambas são funções que recebem um parâmetro x e o aplicam à expressão 3 (x x) + 4 * x + 1, a única diferença é que em f1, sua definição é feita estaticamente, enquanto nf1 foi criada dinamicamente. Mais uma vez também, podemos evidenciar a importância de funções como objetos de primeira classe e funções de ordem superior.