Haskell/Lambdas e operadores: diferenças entre revisões

m
<source> -> <syntaxhighlight> (phab:T237267)
mSem resumo de edição
m (<source> -> <syntaxhighlight> (phab:T237267))
 
Relembrando os exemplos do capítulo [[Haskell/Listas II|Listas II]], suponha que queiramos dobrar todos os elementos de uma lista. Uma possível função para este trabalho seria:
 
<sourcesyntaxhighlight lang="haskell">
dobrarLista ls = map dobro ls
where dobro x = 2 * x
</syntaxhighlight>
</source>
 
Ou ainda:
 
<sourcesyntaxhighlight lang="haskell">
dobrarLista ls = let dobro x = 2 * x
in map dobro ls
</syntaxhighlight>
</source>
 
Outra solução, porém, seria usar uma ''expressão lambda'' para representar a função auxilar <code>dobro</code> sem precisar usar <code>let</code> ou <code>where</code>:
 
<sourcesyntaxhighlight lang="haskell">
dobrarLista ls = map (\x -> 2 * x) ls
</syntaxhighlight>
</source>
 
Antes de entendermos a notação, precisamos fazer uma breve correlação entre Matemática e Computação.
Há um jeito, porém, de dar nomes às funções anônimas. Basta declarar uma variável que seja a função anônima. Por exemplo:
 
<sourcesyntaxhighlight lang="haskell">
pitagoras = \x y -> sqrt (x^2 + y^2)
</syntaxhighlight>
</source>
 
Acabamos de criar a função <code>pitagoras</code> a partir de uma expressão lambda que possui dois argumentos. Podemos testar no GHCi:
Novos operadores podem ser definidos como quaisquer outras funções, basta não usar caracteres alfanuméricos em seus nomes e colocando parênteses na assinatura de tipo. Por exemplo, vejamos a definição da função <code>(\\)</code> do módulo <code>Data.List</code>, a qual elimina os elementos iguais de duas listas:
 
<sourcesyntaxhighlight lang="haskell">
(\\) :: (Eq a) => [a] -> [a] -> [a]
xs \\ ys = foldl (\zs y -> delete y zs) xs ys
</syntaxhighlight>
</source>
 
A segunda linha também poderia ser escrita de forma infixa, mas é opcional:
<sourcesyntaxhighlight lang="haskell">
(\\) xs ys = foldl (\zs y -> delete y zs) xs ys
</syntaxhighlight>
</source>
 
=== Seções ===
''Seções'' são um tipo de açúcar sintático que permite criamos novas funções a partir da aplicação parcial de operadores. Por exemplo, a função <code>dobro</code> que vimos antes pode ser definida como:
 
<sourcesyntaxhighlight lang="haskell">
dobro x = (2*) x
</syntaxhighlight>
</source>
 
Ou ainda, usando a notação de ponto livre:
 
<sourcesyntaxhighlight lang="haskell">
dobro = (2*)
</syntaxhighlight>
</source>
 
Assim sendo, podemos escrever a função <code>dobrarLista</code> de maneira ainda mais concisa, sem usar expressões lambda:
 
<sourcesyntaxhighlight lang="haskell">
dobrarLista ls = map (*2) ls
</syntaxhighlight>
</source>
 
Deve-se notar, entretanto, que para a maioria dos operadores, a ordem do argumento fixo importa:
#
# Teste as seguintes linhas no GHCi:
:: <sourcesyntaxhighlight lang="haskell">
norma3D x y z = sqrt (x^2 + y^2 + z^2)
nomra3D' a b = a `norma3D` b
</syntaxhighlight>
</source>
:: Se a notação infixa só pode ser usada com funções de dois argumentos, por que a definição de <code>norma3D'</code> é válida? Dica: observe os tipos de cada uma das funções e lembre-se de ''[[Haskell/Listas II#Currying|currying]]''.}}
251

edições