2

Below are three functions that need to be composed and give us the output 30:

const add = (a) => a + 10;
const mul = (a) => a * 10;
const divide = (a) => a / 5; 

// How to implement `compositionFunction`?
compositionFunction(add, mul, divide)(5);
//=> 30

Expected output is 30 because:

5 + 10 = 15
15 * 10 = 150
150 / 5 = 30
8
  • 1
    create a function or another const with all three operation ? Commented Mar 24, 2022 at 14:34
  • 1
    None of your functions return anything. You should read about arrow function syntax. Commented Mar 24, 2022 at 14:35
  • 4
    What the OP refers to as customComposeFn actually is a pipe approach. Commented Mar 24, 2022 at 14:36
  • 1
    @PeterSeliger yes, often called "pipe". Compose often goes in the opposite direction. Reasoning being f(g(x)) = compose(f, g)(x). Commented Mar 24, 2022 at 14:37
  • 1
    ... which meanwhile got provided by R4ncid Commented Mar 24, 2022 at 14:37

4 Answers 4

3

Something like this

const add = (a) =>  a + 10 ;
const mul = (a) =>  a * 10 ;
const divide = (a) => a / 5 ; 
// How to use this function -----

const customComposeFn = (...f) => v => f.reduce((res, f) => f(res), v)

console.log(customComposeFn(add, mul, divide)(5));

Sign up to request clarification or add additional context in comments.

3 Comments

compose is colloquially know as right-to-left function composition. What you've done is pipe IMHO.
@customcommander to be fair, that's what OP asked for. I clarified the title of the question. I do agree with you, though - compose is most often right-to-left.
With just recursion it could be const compose = (f, ...rest) => f ? x => compose(...rest)(f(x)) : x => x; but I like that you used .reduce much better!
2

There are two flavours of function composition:

  1. left-to-right function composition aka pipe
  2. right-to-left function composition aka compose

Here's a recursive implementation just for fun:
This assumes that there are at least two functions to compose

const compose = (...fn) => {
  const [[f, g], x] = [fn.slice(-2), fn.slice(0, -2)];
  const h = a => f(g(a));
  return x.length ? compose(...x, h) : h;
}

const pipe = (...fn) => {
  const [f, g, ...x] = fn;
  const h = a => g(f(a));
  return x.length ? pipe(h, ...x) : h;
}

Let's try:

const foo = x => x + 'foo';
const bar = x => x + 'bar';
const baz = x => x + 'baz';

pipe(foo, bar, baz)('');
//=> 'foobarbaz'

compose(foo, bar, baz)('');
//=> 'bazbarfoo'

1 Comment

You can peel off an argument rather than slicing like this: const compose = (f, ...rest) => f ? x => compose(...rest)(f(x)) : x => x;, which returns an identity function in the terminal case.
-1

const add = (a) => a + 10;
const mul = (a) => a * 10;
const divide = (a) => a / 5;
const customComposeFn = (...fn) => {
    return function (arg) {
        if (fn.length > 0) {
            const output = fn[0](arg);
            return customComposeFn(...fn.splice(1))(output);
        } else {
            return arg;
        }
    };
};
const res = customComposeFn(add, mul, divide)(5);
console.log(`res`, res);

Comments

-1

Here's what I would do:

function customComposeFn(...funcs) {
  return function(arg) {
    let f, res = arg;
    while (f = funcs.shift()) {
      res = f(res)
    }
    return res;
  }
}

const add = a => a + 10;
const mul = a => a * 10;
const divide = a => a / 5;
// How to use this function -----
console.log(customComposeFn(add, mul, divide)(5));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.