Currying e Aplicação Parcial
Currying e aplicação parcial são dois conceitos bastante presentes na programação funcional. Os dois conceitos operam diretamente em funções com o objetivo de alterar seu tipo.
Primeiro vamos entender como exemplificar o tipo de uma função, para isso, vamos utilizar uma sintaxe parecida com a sintaxe utilizada na linguagem F#, também da plataforma .NET.
Em F# o tipo da função é definido por: parâmetro -> retorno
Logo, uma função com um parâmetro do tipo int
e um retorno do tipo bool
pode ser descrita como: int -> bool
Quando houverem múltiplos parâmetros iremos representar aqui (diferente do F#) como: int, int, int -> bool
Com isso, estabelecemos uma sintaxe para definir o tipo de uma função.
Agora vamos entender o problema que estas duas técnicas auxiliam na resolução.
A programação funcional é baseada principalmente no conceito de funções. Por definição, uma função matemática deve possuir apenas um parâmetro (domínio) e um retorno (alcance).
Logo, isso implicaria que, todas as funções escritas em um código funcional devem conter apenas um parâmetro, como fazer isso? - Currying
Entendendo Currying
O processo de currying consiste em quebrar funções de N parâmetros em N funções, onde cada função irá receber apenas um parâmetro e retornar uma nova função que espera os parâmetros restantes.
Logo, uma função de soma, que seria representada por: int, int -> int
Ao passar pelo processo de currying pode ser representada por: int -> int -> int
Vamos realizar um passo-a-passo do processo de currying em uma função simples, que realiza a soma de 2 valores.
Primeiro vamos definir a função como:
Podemos utilizar esta função normalmente, conforme código:
Ao realizar o processo de currying na função add
o retorno será uma função do tipo Func<int, Func<int,int>>
, ou seja, será uma função que receberá um valor inteiro e retornará um nova função esperando o segundo valor inteiro.
Quando esta segunda função receber o último parâmetro ela irá realizar o processamento proposto por add
.
Veja como podemos realizar o currying com a Tango.
Veja que a forma de informar os parâmetros na função addCurried
é um pouco diferente, isso porque ele gera uma série de funções, onde cada uma espera apenas um parâmetro.
A Tango também fornece o Curry
através de métodos de extensão para os delegates Func
, portanto ao você também poderá realizar a operação descrita anteriormente da seguinte forma:
Entendendo a Aplicação Parcial
A aplicação parcial é um pouco diferente do processo de Currying, mas também envolve a questão dos tipos de uma função.
Através da aplicação parcial é possível realizar a chamada de um método sem informarmos todos os parâmetros. Como resultado desta operação, será retornada uma nova função que espera todos os parâmetros restantes.
Veja as diferenças entre Currying e aplicação parcial em uma função que soma três números inteiros.
Esta seria o tipo da função de soma: int, int, int -> int
Ao realizar o Currying nesta função o resultado obtido seria: int -> int -> int -> int
Neste ponto a aplicação parcial funciona completamente diferente do processo de Currying, poderíamos inclusive, realizar diferentes aplicações parciais nesta função.
Ao informar apenas um parâmetro o resultado obtido seria: int, int -> int
Informando dois parâmetros o resultado obtido seria: int -> int
Similar ao processo de Currying, a operação fundamental descrita pela função só é executada quando todos os parâmetros forem informados, independente da quantidade de funções intermediárias geradas.
Veja a implementação descrita, primeiro através de currying:
Utilizando aplicação parcial com apenas um parâmetro:
Utilizando aplicação parcial com dois parâmetros:
Todos os métodos disponíveis para aplicação parcial e Currying operam em métodos de até 4 parâmetros, podendo retornar qualquer tipo, inclusive void
.
Além disso, eles podem ser utilizados como métodos estáticos das classes Currying
e PartialApplication
ou como extensões para Func
e Action
.
Last updated