Skip to content

Instantly share code, notes, and snippets.

@cowboyd
Last active October 11, 2018 15:42
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cowboyd/795a58a9f4e5280602b47270dafdfe46 to your computer and use it in GitHub Desktop.
Save cowboyd/795a58a9f4e5280602b47270dafdfe46 to your computer and use it in GitHub Desktop.
Funcadelic typeclass implementations for AsyncFunction
/**
* There's some pretty awesome low-level composition that you can do with async functions:
* Check out funcadelic! https://github.com/cowboyd/funcadelic.js
*/
import { Functor, Semigroup, Monoid } from 'funcadelic';
const AsyncFunction = (async function() {}).constructor;
/**
* It's a Functor!
* `map` returns a new async function that awaits the
* result of the old async function and then applies `fn` to it.
*/
Functor.instance(AsyncFunction, {
map(fn, asyncFn) {
return async (...args) => fn(await asyncFn(...args));
}
})
/**
* It's a Semigroup!
* `append` takes two async functions, f and g, and returns a new async function
* that awaits the result of g, and then awaits the result of f invoked with the result of g.
* In a nutshell: function composition for async functions.
*/
Semigroup.instance(AsyncFunction, {
append(f, g) {
return async (...args) => await f(await g(...args));
}
})
/**
* Yup! monoid too. In this case, the zero or empty value is just the
* async identity function.
*/
Monoid.instance(AsyncFunction, {
empty() {
return async x => x;
}
})
/**
* Monad alert! flatMap invokes awaits the result of asyncFn, then
* applies `fn` to the result. `fn` can return a new asyncFunction,
* in which case, flatMap will await its return (effectively replacing itself)
* Otherwise, the result is the result.
*/
Monad.instance(AsyncFunction, {
flatMap(fn, asyncFn) {
return async function(...args) {
let result = fn(await asyncFn(...args));
if (result instanceof AsyncFunction) {
return await result(...args);
} else {
return result;
}
}
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment