NodersJS
Published in

NodersJS

Osman Cea

Dec 22, 2019

8 min read

Introducción a Ramda.js - Parte 0

Conceptos generales sobre programación funcional.

Photo by Andres Iga on Unsplash

Funciones puras y efectos colaterales

Currying

// addSeveralNumbers es una función curriada que suma los 6 parámetros que recibe
const addSeveralNumbers = (a, b, c, d, e, f) => { /* ... */ }
const addAllButFirst = addSeveralNumbers(1);
const addRemainingTwo = addSeveralNumbers(1, 2, 3, 4);
addAllButFirst(2, 3, 4, 5, 6) === addRemainingTwo(5, 6) // true
const addSeveralNumbers = a => {
return b => {
return c => {
return d => {
return e => {
return f => {
return a + b + c + d + e + f;
}
}
}
}
}
};
const addSeveralNumbers = a => b => c => d => e => f => 
(a + b + c + d + e + f);
const addRemainingTwo = addSeveralNumbers(1)(2)(3)(4);
addSeveralNumbers(1)(2)(3)(4)(5)(6); // 21
|-- 1 => ...etc --|
|---- 2 => ...etc ---|
|------ 3 => ...etc ----|
|-------- 4 => ...etc -----|
|---------- 5 => ...etc ------|
|------------ 6 => 1 + 2 + 3 + 4 + 5 + 6;
import { curry } from 'ramda';const addSeveralNumbers = curry((a, b, c, d, e, f) => {
return a + b + c + d + e + f;
});
addSeveralNumbers(1, 2, 3, 4, 5, 6) // 21
addSeveralNumbers(1, 2, 3, 4)(5, 6) // 21
addSeveralNumbers(1)(2, 3, 4, 5, 6) // 21
addSeveralNumbers(1)(2)(3)(4)(5)(6) // 21

¿Cuándo es útil el currying?

function map(projectionFn, arr) {
const result = [];
for (const item of arr) {
result.push(projectionFn(item));
}
return result;
}
map(x => x * 2, [1, 2, 3, 4]); // [2, 4, 6, 8]
const timesTwo = x => x * 2;map(timesTwo, [1, 2, 3, 4]); // [2, 4, 6, 8]
map(timesTwo, [4, 2]); // [8, 4]
map(timesTwo, [1, 1, 1, 3]); // [2, 2, 2, 6]
map(timesTwo, [5, 7, -3]); // [10, 14, -6]
const timesTwo = x => x * 2;
const mapTimesTwo = arr => {
return map(timesTwo, arr);
}
mapTimesTwo([1, 2, 3, 4]); // [2, 4, 6, 8]
mapTimesTwo([4, 2]); // [8, 4]
mapTimesTwo([1, 1, 1, 3]); // [2, 2, 2, 6]
mapTimesTwo([5, 7, -3]); // [10, 14, -6]
const timesTwo = x => x * 2;
const timesThree = x => x * 3;
const mapTimesTwo = arr => map(timesTwo, arr);
const mapTimesThree = arr => map(timesThree, arr);
import { curry } from 'ramda';const map = curry((projectionFn, arr) => {
const result = [];
for (const item of arr) {
result.push(projectionFn(item));
}
return result;
});
const timesTwo = x => x * 2;const fn = map(timesTwo);
const mapTimesTwo = arr => fn(arr);
const log = message => console.log(message);log('foo'); // "foo"
console.log('foo'); // "foo"
const log = console.log; 
const timesTwo = x => x * 2;
const timesThree = x => x * 3;
const mapTimesTwo = map(timesTwo);
const mapTimesThree = map(timesThree);
mapTimesTwo([1, 2, 3, 4]); // [2, 4, 6, 8]
mapTimesTwo([4, 2]); // [8, 4]
mapTimesThree([1, 2, 3]); // [3, 6, 9]
mapTimesThree([5, 7]); // [15, 21]
Wow 😮

Point-free style

import { map } from 'ramda';const mapTimesTwo = arr => map(x => 2 * x, arr);
import { map, multiply } from 'ramda';const mapTimesTwo = arr => map(x => multiply(2, x), arr);
import { map, multiply } from 'ramda';const mapTimesTwo = arr => map(multiply(2), arr);
import { map, multiply } from 'ramda';const mapTimesTwo = map(multiply(2));mapTimesTwo([1, 2, 3, 4]); // [2, 4, 6, 8]
Anotación de tipos inferidos en mapTimesTwo.
Anotación de tipos en multiply.

Inmutabilidad

¿Por qué? Porque nos gusta.