Skip to content

Instantly share code, notes, and snippets.

@ifyoumakeit
Created November 25, 2017 02:21
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 ifyoumakeit/e8b064b268aa22115b7a07c1a101adc5 to your computer and use it in GitHub Desktop.
Save ifyoumakeit/e8b064b268aa22115b7a07c1a101adc5 to your computer and use it in GitHub Desktop.
Transducers / Composing
/**
* Composes functions like c(f, g) === f(g(x)).
* @param {arguments} fns Multiple functions w/ map/reduce.
* @returns reducer seeded with identity function.
* @example compose(x => x + 2, x => x - 1)(5) // 6 (5 + 2 -1)
*/
const compose = (...fns) => {
return fns.reduce((acc, fn) => {
return (...args) => {
return acc(fn(...args));
};
}, x => x);
};
/**
* Map re-written to return reducer
* @param {function} xf Transform function
* @returns reducer function
*/
const map = xf => {
return reducer => {
return (acc, val) => {
return reducer(acc, xf(val));
};
};
};
/**
* Filter re-written to return reducer
* @param {function} predicate Return boolean based on value;
* @returns reducer function of present last.
*/
const filter = predicate => {
return reducer => {
return (acc, val) => {
return predicate(val) ? reducer(acc, val) : acc;
};
};
};
// Example functions
// Takes single value, returns value.
const addTwo = val => 2 + val;
const timesTwo = val => val * 2;
const isTwo = val => val === 2;
// Accumulator function, pushs direct onto array.
// Connects each function to each other.
const pushReducer = (acc, val) => acc.concat(val);
/**
* Compose multiple functions in a row.
* Reads LEFT to RIGHT because of reduce function.
* What transducers really do is transform reducing functions,
* not actual values; they take one reducing function and
* return another one that works by transforming its values and
* passing the results to that passed-in reducing function.
* http://isaaccambron.com/blog/2014/12/13/transducer-composition.html
*/
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].reduce(
compose(filter(isTwo), map(addTwo), map(timesTwo))(pushReducer),
[]
);
/**
* Read RIGHT to LEFT when not using reducer.
* 2 * 2 = 4
* 4 + 2 = 6
*/
const foo = compose(x => x + 2, x => x * 2)(2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment