Programação Funcional em JavaScript: Técnicas Avançadas

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução à programação funcional em nível avançado

\n\n

Programação funcional (PF) é um paradigma que trata a computação como a execução de funções matemáticas e evita a mudança de estado e dados mutáveis. Em JavaScript, especialmente no ambiente Node.js, a PF está se tornando cada vez mais popular devido à sua previsibilidade, testabilidade e paralelismo.

\n\n

Se você já domina os fundamentos da PF (funções puras, funções de ordem superior, map, filter, reduce), é hora de passar para o próximo nível. Neste artigo, abordaremos conceitos avançados: currying, composição, mônadas e trabalho com dados imutáveis.

\n\n

1. Currying e aplicação parcial

\n\n

O que é currying?

\n

Currying é o processo de transformar uma função que recebe vários argumentos em uma sequência de funções, cada uma recebendo um único argumento. Isso permite criar funções especializadas com base em funções gerais.

\n\n
// Função normal\nconst add = (a, b, c) => a + b + c;\nconsole.log(add(1, 2, 3)); // 6\n\n// Versão curried\nconst curriedAdd = a => b => c => a + b + c;\nconsole.log(curriedAdd(1)(2)(3)); // 6\n\n// Função universal de currying\nconst curry = (fn) => {\n  const arity = fn.length;\n  const resolver = (...args) => {\n    if (args.length < arity) {\n      return (...nextArgs) => resolver(...args, ...nextArgs);\n    }\n    return fn(...args);\n  };\n  return resolver;\n};\n\nconst multiply = (a, b, c) => a * b * c;\nconst curriedMultiply = curry(multiply);\nconsole.log(curriedMultiply(2)(3)(4)); // 24\nconsole.log(curriedMultiply(2, 3)(4)); // 24
\n\n

Aplicação parcial

\n

Aplicação parcial é a fixação de parte dos argumentos de uma função, criando uma nova função com menos argumentos. Ao contrário do currying, a aplicação parcial não exige uma sequência estrita de chamadas.

\n\n
const partial = (fn, ...presetArgs) => (...laterArgs) => fn(...presetArgs, ...laterArgs);\n\nconst greet = (greeting, name) => `${greeting}, ${name}!`;\nconst sayHello = partial(greet, 'Hello');\nconst sayHi = partial(greet, 'Hi');\n\nconsole.log(sayHello('Alice')); // Hello, Alice!\nconsole.log(sayHi('Bob'));     // Hi, Bob!
\n\n

2. Composição de funções

\n\n

Composição avançada

\n

Composição é o processo de combinar várias funções para criar uma nova função. Na PF avançada, usamos composição da direita para a esquerda (compose) e da esquerda para a direita (pipe).

\n\n
// Composição simples (da direita para a esquerda)\nconst compose = (...fns) => (value) => fns.reduceRight((acc, fn) => fn(acc), value);\n\n// Composição da esquerda para a direita (pipe)\nconst pipe = (...fns) => (value) => fns.reduce((acc, fn) => fn(acc), value);\n\n// Exemplo: processamento de string\nconst trim = (str) => str.trim();\nconst toLowerCase = (str) => str.toLowerCase();\nconst capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);\nconst removeSpaces = (str) => str.replace(/\\s+/g, '-');\n\nconst slugify = compose(capitalize, toLowerCase, trim, removeSpaces);\n// Equivalente: removeSpaces(trim(toLowerCase(capitalize("  Hello World  "))))\n\nconsole.log(slugify('  Hello World  ')); // Hello-world
\n\n

Transdutores (Transducers)

\n

Transdutores são a composição de funções de transformação que operam em qualquer estrutura de dados iterável. Eles permitem combinar várias operações (por exemplo, map e filter) em uma única passagem.

\n\n
const transducer = (mapper, predicate) => (reducer) => (acc, value) => {\n  const mapped = mapper(value);\n  return predicate(mapped) ? reducer(acc, mapped) : acc;\n};\n\nconst double = (x) => x * 2;\nconst isEven = (x) => x % 2 === 0;\n\nconst processNumbers = transducer(double, isEven);\nconst sumReduc                

Blogs

Book Recommendations