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.