-
-
Save scott-christopher/39d982cac2a29ced5a6a to your computer and use it in GitHub Desktop.
Promise applicative example
This file contains hidden or 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
// Apply a function in a Promise to a value in a Promise once both resolve (used by `promiseLift` below) | |
// :: Promise (a -> b) -> Promise a -> Promise b | |
var promiseAp = R.curry((promiseFn, promiseArg) => | |
promiseFn.then(fn => promiseArg.then(arg => fn(arg))) | |
); | |
// Lift a plain function to accept Promise arguments | |
// :: (a -> ...n -> b) -> Promise a -> ...Promise n -> Promise b | |
var promiseLift = (fn) => { | |
var run = R.curryN(fn.length, (firstArg) => | |
R.reduce( | |
promiseAp, | |
firstArg.then(R.curry(fn)), // `fn` must be curried for partial application | |
R.drop(1, arguments) | |
)); | |
// Apply any arguments provided along with `fn` | |
return arguments.length > 1 ? R.apply(run, R.drop(1, arguments)) : run; | |
}; | |
// Example function for creating a Promise that executes a given `fn` after some `ms` delay | |
var delay = R.curry((ms, fn) => new Promise(res => setTimeout(res, ms)).then(fn)); | |
// Some example Promises | |
var a = delay(500, R.always(1)); | |
var b = delay(1000, R.always(2)); | |
var c = delay(1500, R.always(3)); | |
// A plain JS function to apply | |
var add3 = (a, b, c) => a + b + c; | |
// Lift the plain function to now accept Promises | |
var promiseAdd3 = promiseLift(add3); | |
// Should print `6` to console immediately | |
promiseAdd3(1, 2, 3).then(console.log.bind(console)); | |
// Should print `6` to console after 1500 ms | |
promiseAdd3(a, b, c).then(console.log.bind(console)); | |
// Alternatively pass all arguments at once | |
promiseLift(add3, a, b, c).then(console.log.bind(console)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment