Haskell/Composição de funções: diferenças entre revisões

[edição não verificada][edição não verificada]
Conteúdo apagado Conteúdo adicionado
mSem resumo de edição
m <source> -> <syntaxhighlight> (phab:T237267)
 
Linha 10:
''Compor funções'' significa aplicar uma função a um argumento e, depois, aplicar outra função ao resultado da primeira função. Veja:
 
<sourcesyntaxhighlight lang=haskell>
f x = x + 3
quadrado x = x ^ 2
</syntaxhighlight>
</source>
 
Podemos compor <code>f</code> e <code>quadrado</code> de duas maneiras:
Linha 32:
Compor duas ou mais funções resulta numa nova função. Se for o caso de sempre usarmos <code>quadrado</code> e <code>f</code> de forma composta, poderíamos definir novas funções para facilitar a programação:
 
<sourcesyntaxhighlight lang="haskell">
quadradoDef x = quadrado (f x)
fDeQuadrado x = f (quadrado x)
</syntaxhighlight>
</source>
 
Há também um outro jeito de compor duas funções: usando o operador de composição <code>(.)</code>. Basta adicionar um ponto entre o nome de duas funções:
 
<sourcesyntaxhighlight lang="haskell">
quadradoDef x = (quadrado . f) x
fDeQuadrado x = (f . quadrado) x
</syntaxhighlight>
</source>
 
Note que as funções ainda são aplicadas da direita para a esquerda: <code>(g . f) x == g(f(x))</code>. O símbolo <code>(.)</code> foi escolhido para representar composição de funções por ser semelhando à notação matemática: <math>(g \circ f)(x) = g(f(x))</math>.
 
Outra simplificação: nossas funções são como expressões matemáticas. Isso quer dizer que ''às vezes'' podemos então escrever
<sourcesyntaxhighlight lang="haskell">quadradoDef x = (quadrado . f) x</sourcesyntaxhighlight>
e eleminar <code>x</code> de ambos os lados, resultando em:
<sourcesyntaxhighlight lang="haskell">quadradoDef = quadrado . f</sourcesyntaxhighlight>
 
Aprenderemos mais sobre funções "sem argumentos" mais tarde. Mas é importante lembra-se desta possibilidade em Haskell desde o começo.
Linha 67:
Outras bibliotecas são também chamadas de ''módulos'', que podem ser ''importados'' no programa. Mais adiante, em capítulos futuros, falaremos sobre o desenvolvimento de módulos e como eles funcionam. Por enquanto, vamos focar em importar alguns módulos básicos. A função <code>permutations</code>, por exemplo, gera todas as permutações possíveis dos elementos de uma lista. Esta operação pode ser bastante útil, entertanto a função não está disponível no <code>Prelude</code>, mas no módulo <code>Data.List</code>. Para importar o módulo de listas (ou qualquer outro) e poder usar suas funções, você deve adicionar uma chamada no topo do seu arquivo <tt>.hs</tt>:
 
<sourcesyntaxhighlight lang="haskell">
import Data.List
 
testarPermutations = permutations "Prelude"
</syntaxhighlight>
</source>
 
Para carregar um módulo numa sessão do GHCi, deve-se usar o comando <code>:module +</code> (ou <code>:m +</code>):
Linha 85:
Antes de seguirmos para o próximo capítulo, vejamos um exemplo das vantagens de se usar funções nativas (ou contidas em outros módulos).<ref group=nota>Este exemplo foi inspirado na demonstração [https://wiki.haskell.org/Simple_unix_tools Simple Unix tools] da [https://wiki.haskell.org/Simple_unix_tools HaskellWiki].</ref> Suponha que você queira uma função que inverta a ordem das palavras contidas num String. Por exemplo, se a entrada fosse "O rato roeu a roupa do rei", a saída seria "rei do roupa a roeu rato O". Uma possível solução seria (não tente entender seu funcionamento, é apenas um caso ilustrativo):
 
<sourcesyntaxhighlight lang="haskell">
inverterPalavras :: String -> String
inverterPalavras entrada = reunirNaoInvertidas (dividirRevertidas entrada)
Linha 118:
go3 rev [] = rev
go3 rev (c:cs) = go3 (c:rev) cs
</syntaxhighlight>
</source>
 
Temos muitos problemas aqui:
Linha 132:
Conhecendo todas essas funções e usando o operador <code>(.)</code>, poderíamos escrever:
 
<sourcesyntaxhighlight lang="haskell">
novaInverterPalavras :: String -> String
novaInverterPalavras entrada = (unwords . reverse . words) entrada
</syntaxhighlight>
</source>
 
Você consegue ver as vantagens?