Poznajemy przeciwieństwo pipe, czyli compose. Kolejne zagadnienie programowania w paradygmacie funkcyjnym. Do dzieła!
Przypomnijmy sobie pipe:
const removeFirstlSlash = (url) => url.startsWith("/") ? url.slice(1) : url;
const removeQueryString = (url) => url.includes("?") ? url.slice(0, url.indexOf("?")) : url;
const pipe = (...fns) => (data) => fns.reduce((acc, fun) => fun(acc), data);
const stripUnwantedParts = pipe(
removeFirstlSlash,
removeQueryString
);
let url = stripUnwantedParts("/blabla/bla?q=term");
console.log(url);
//blabla/bla
Aby zrozumieć compose potrzebny nam będzie inny przykład:
const addTwo = (num) => num + 2;
const mulByTwo = (num) => num * 2;
const pipe = (...fns) => (data) => fns.reduce((acc, fun) => fun(acc), data);
const piped = pipe(
addTwo,
mulByTwo
);
let num = 2;
let result = piped(num);
console.log(result);
//8
Ok, teraz compose:
const addTwo = (num) => num + 2;
const mulByTwo = (num) => num * 2;
const pipe = (...fns) => (data) => fns.reduce((acc, fun) => fun(acc), data);
const compose = (...fns) => (data) => fns.reduceRight((acc, fun) => fun(acc), data);
const piped = pipe(
addTwo,
mulByTwo
);
const composed = compose(
addTwo,
mulByTwo
);
let num = 2;
let result1 = piped(num);
let result2 = composed(num);
console.log(result1);
//8
console.log(result2);
//6
Jak widać compose idzie od dołu do góry (zatem wymaga reduceRight, idącego od prawej do lewej po tablicy z funkcjami). To jedna z tych sytuacji, gdzie reduceRight ma jakieś swoje zastosowanie.