Skip to content

Instantly share code, notes, and snippets.

@scott-christopher
Last active August 29, 2015 14:26
Show Gist options
  • Save scott-christopher/39d982cac2a29ced5a6a to your computer and use it in GitHub Desktop.
Save scott-christopher/39d982cac2a29ced5a6a to your computer and use it in GitHub Desktop.
Promise applicative example
// 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