um dos princípios que todo programador procura cumprir é DRY (Don’t Repeat YourSelf), com Currying vamos ver como fazer isso com nossas funções é bastante simples e útil.
este conteúdo eu publiquei primeiro no meu ne onssletter, uma semana depois de postar o ne onssletter eu publico no meu blog, se você quiser ser o primeiro a ler Inscreva-se
a maneira como normalmente escrevemos nossas funções é:
//ES2015const divisible = (num, mod) => num % mod;//ES5var divisible = function(num, mod) { return num % mod;}
para poder executar esta função devemos passar dois argumentos, mas se quiséssemos ter uma função que verifique exclusivamente se um número é par teríamos que escrever uma nova função. Neste momento, é útil ter uma função currificada.
para antes de entender como funciona uma função currificada devemos conhecer alguns conceitos.
as funções são cidadãos de primeira classe, isto significa que as funções são objetos, podem ser passadas como argumentos, armazenadas em variáveis e retornadas dentro de outras Funções Funções de alta ordem em JavaScript
um closure é quando uma função é capaz de lembrar e acessar um lexical scope, mesmo quando a função é executada por fora do lexical scope. Entendendo os closures em JavaScript
se uma função recebe mais de um parâmetro, ela pode ser reescrita como, uma função que pega um parâmetro e retorna umfunção, é por sua vez recebe um parâmetro e retorna o resultado. Calculo lambda em JavaScript
¿o que é Currying?
Curry é poder chamar uma função com menos parâmetros do que espera, esta retorna uma função que espera os parâmetros restantes e retorna o resultado.
desta maneira nós poderíamos reescrever a função do começo como
//ES2015const divisible = mod => num => num % mod;//ES5var divisible = function (mod) { return function (num) { return num % mod; }}
para chamar esta função temos duas opções
- passar os argumentos executando a funções
divisible(10)(2)
- passando um argumento e recebendo uma função que lembra esse argumento
const divisibleEn3 = divisible(3);divisibleEn3(10)
Como vemos escrever uma função currificada não é complicado, mas poderíamos torná-la um pouco mais natural como escrevemosqualquer função.
para isso, podemos usar Lodash ou Ramda que possuem um método curry, que nos permite currificar qualquer função dessa maneira.
import { __, curry, map } from 'ramda';const composeNombre = curry( (primer, apellido) => `${primer} ${apellido}`);const familiaJaimes = composeNombre(__, 'Jaimes')const nombres = console.log(map(familiaJaimes, nombres))
vejamos um exemplo mais útil retirado do Mostly adequate guide to functional programming
import { curry } from 'ramda';// Estas funciones las puedes conseguir dentro de Ramda o Lodashvar match = curry(function(what, str) { return str.match(what);});var replace = curry(function(what, replacement, str) { return str.replace(what, replacement);});var filter = curry(function(f, ary) { return ary.filter(f);});var map = curry(function(f, ary) { return ary.map(f);});var hasSpaces = match(/\s+/g);hasSpaces("hello world");// hasSpaces("spaceless");// nullfilter(hasSpaces, );// var findSpaces = filter(hasSpaces);// function(xs) { return xs.filter(function(x) { return x.match(/\s+/g) }) }findSpaces();//
vantagens de Currying
- Podemos criar novas funções simplesmente passando nossas funções de base com alguns parâmetros.
- Podemos transformar qualquer função que trabalhe com um único elemento em uma que trabalhe com uma lista, envolvendo-a em um map.
- você pode escrever pequenos pedaços de código que são mais fácil de reutilizar.
- é fácil raciocinar sobre elas.
- escrever funções currificadas nos permitirá compor funções.