Skip to content

Instantly share code, notes, and snippets.

@neftaly
Last active December 5, 2021 14:24
Show Gist options
  • Select an option

  • Save neftaly/6e11268f1cd230094c81 to your computer and use it in GitHub Desktop.

Select an option

Save neftaly/6e11268f1cd230094c81 to your computer and use it in GitHub Desktop.
ES6 Compose
const compose = (...args) => initial => args.reduceRight(
(result, fn) => fn(result),
initial
);
@neftaly
Copy link
Copy Markdown
Author

neftaly commented Jun 21, 2016

Type signature is something like compose :: (c, b, a, ...) -> (x, y, z, ...) -> ...(c(b(a(x, y, z, ...))))

@iamstarkov
Copy link
Copy Markdown

iamstarkov commented Aug 24, 2016

@neftaly

const compose = ([ firstArg, ...restArgs ]) => (...initial) => restArgs.reduceRight(
    (result, fn) => fn(result),
    firstArg(...initial)
);

this implementation is broken in sense that for compose right most function can be any arity, and in this example its left most


// Same thing, written differently
const compose = (...args) => (...initial) => args.reduceRight(
    (result, fn) => [ fn(...result) ],
    initial
)[0];

this implementation will be broken if any function inside compose will return array as a value, so next function will take this array not as first argument, but as arguments as a whole

@iamstarkov
Copy link
Copy Markdown

iamstarkov commented Aug 24, 2016

@neftaly @meChrisReed

Working as intended implementation should look like this:

const compose = (...fns) => {
  const [tailFn, ...restFns] = fns.reverse();
  return (...args) => restFns.reduce(
    (value, fn) => fn(value),
    tailFn(...args)
  );
};

const pipe = (...fns) => compose(...fns.reverse());

Or other way around

const pipe = (headFn, ...restFns) => (...args) => restFns.reduce(
  (value, fn) => fn(value),
  headFn(...args)
);

const compose = (...fns) => pipe(...fns.reverse());

@weiying-chen
Copy link
Copy Markdown

@iamstarkov How does the functions handle functions with two arguments? Could you give me an example or how to modify the code so it handles them?

@WaldoJeffers
Copy link
Copy Markdown

Hello, here's my version https://gist.github.com/WaldoJeffers/905e14d03f4283599bac753f73b7716b. Does it cover your use cases ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment