Programación funcional en JavaScript Parte 2 - Combinadores
Pawel Ged
Vue.js Desarrollador
Esta es la segunda parte de nuestra serie de artículos dedicados al poder de la programación funcional en JavaScript. Consulta este artículo para ampliar tus conocimientos sobre Combinadores.
Introducción a los combinadores
Los combinadores son funciones de nivel superior que permiten combinar funciones, variables u otros combinadores. Normalmente, no contienen declaraciones de variables propias ni lógica de negocio. Son los únicos que permiten el control en un programa de funciones.
En este artículo intentaré tratar algunos de ellos:
Toque
Curry
Tubería/Composición
Horquilla
Alternancia
Secuencia
Toque
Un combinador es muy útil para funciones que no devuelven nada. Toma la función a la que va el parámetro y luego lo devuelve.
const [items, setItems] = useState(() => [])
axios
.get('http://localhost')
.then({ datos } => {
setItems(datos)
console.log(datos)
onLoadData(datos)
}).then(...) // devuelve undefined - los datos de la promesa han sido modificados
Ejemplo declarativo
const [items, setItems] = useState(() => [])
axios
.get('http://localhost')
.then(({ datos }) => datos)
.then(tap(setItems)) // (datos) => { setItems(datos); return datos }
.then(tap(console.log)) // un then = una función = una responsabilidad
.then(tap(onLoadData))
.then(...) // todavía acceso a los datos originales
// fácil de mantener el principio de abrir/cerrar
Curry
Divide los argumentos de una función y permite llamarlos secuencialmente.
const suma = (a, b, c) => a + b + c
const currySuma = curry(suma)
/*
posibles llamadas
currySuma(a)(b)(c),
currySuma(a)(b,c),
currySuma(a,b)(c),
currySuma(a,b,c)
*/
currySum(1) // (b, c) => 1 + a + b o (b) => (c) => 1 + a + b
currySum(5)(10) // (c) => 5 + 10 + b
currySum(5, 10) // (c) => 5 + 10 + b
currySuma(5)(10)(20) // 35
currySuma(5, 10)(20) // 35
currySuma(5)(10, 20) // 35
const dividirPor = curry((a, b) => b / a)
const multiplicarPor = curry((a, b) => a * b)
const dividePorDos = dividePor(2)
divideByTwo(10) // devuelve 5
const multiplicarPorCinco = multiplicarPor(5)
multiplyByFive(10) // devuelve 50
Tubería/Composición
Mediante la composición, es posible pasar datos de una función a otra. Es importante que las funciones tomen el mismo número de argumentos. La diferencia entre pipe y compose es que la primera ejecuta la función de la primera a la última, y compose las llama desde el final.
const longitud = (array) => array.longitud
const suma = (array) => array.reduce((a, b) => a + b, 0)
const divide = (a, b) => a / b
const media aritmética = fork(divide, suma, longitud)
arithmeticAverage([5, 3, 2, 8, 4, 2]) // devuelve 4
Alternancia
Este combinador toma dos funciones y devuelve el resultado de la primera si es verdadero. En caso contrario, devuelve el resultado de la segunda función.