Created
November 25, 2017 02:21
-
-
Save ifyoumakeit/e8b064b268aa22115b7a07c1a101adc5 to your computer and use it in GitHub Desktop.
Transducers / Composing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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