Skip to content

Instantly share code, notes, and snippets.

@petsel
Last active September 3, 2020 16:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save petsel/b17e5f6f458ccd550a51662354d2b782 to your computer and use it in GitHub Desktop.
Save petsel/b17e5f6f458ccd550a51662354d2b782 to your computer and use it in GitHub Desktop.
// see: "Compose in JavaScript, not applying functions correctly?" asked by Dan Mantyla - Nov 10, 2014
// answer: [https://stackoverflow.com/questions/26835095/compose-in-javascript-not-applying-functions-correctly/28880612#28880612]
(function (Function, Object) {
const fctPrototype = Function.prototype;
const FUNCTION_TYPE = (typeof Function);
function isFunction(type) {
return (
(typeof type == FUNCTION_TYPE)
&& (typeof type.call == FUNCTION_TYPE)
&& (typeof type.apply == FUNCTION_TYPE)
);
}
function getSanitizedTarget(target) {
/* eslint-disable */
/* jshint ignore:start */
/* ignore jslint start */
/* no-eq-null */
return ((target != null) && target) || null;
/* ignore jslint end */
/* jshint ignore:end */
/* eslint-enable */
}
function compose/*Modifier*/(previous, target) {
// previous target.
target = getSanitizedTarget(target);
const proceed = this;
return (
isFunction(previous) &&
isFunction(proceed) &&
function (value) {
// current context.
const context = getSanitizedTarget(this);
return proceed.call(context, previous.call(target, value));
}
) || proceed;
}
// compose.toString = () => 'compose() { [native code] }';
Object.defineProperty(fctPrototype, 'compose', {
configurable: true,
writable: true,
value: compose/*Modifier*/
});
// provide static implementation as well.
function staticCompose/*Modifier*/(proceed, previous, target) {
return compose.call(proceed, previous, target);
}
// staticCompose.toString = () => 'compose() { [native code] }';
// staticCompose.toString = () => 'staticCompose() { [native code] }';
Object.defineProperty(Function, 'compose', {
configurable: true,
writable: true,
value: staticCompose/*Modifier*/
});
}(Function, Object));
// see: "Curry and Function Composition" by Eric Elliott at "Medium" - Nov 13, 2018
// [https://medium.com/javascript-scene/curry-and-function-composition-2c208d774983#fd1b]
//
// ... const compose = (f, g) => x => f(g(x)); ...
//
// ... const compose = (...fns) => x => fns.reduceRight( (y, f) => f(y), x);
// ... const pipe = (...fns) => x => fns.reduce( (y, f) => f(y), x);
(function (Function, Object) {
const FUNCTION_TYPE = (typeof Function);
function isFunction(type) {
return (
(typeof type == FUNCTION_TYPE)
&& (typeof type.call == FUNCTION_TYPE)
&& (typeof type.apply == FUNCTION_TYPE)
);
}
function aggregateValue(value, fct) {
return fct(value);
}
function composeAll(...fctList) {
return (value => fctList
.flat()
.filter(isFunction)
.reduceRight(aggregateValue, value)
);
}
function pipeAll(...fctList) {
return (value => fctList
.flat()
.filter(isFunction)
.reduce(aggregateValue, value)
);
}
Object.defineProperty(Function, 'composeAll', {
configurable: true,
writable: true,
value: composeAll
});
Object.defineProperty(Function, 'pipeAll', {
configurable: true,
writable: true,
value: pipeAll
});
}(Function, Object));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment