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.