Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
An example container used for functional programming, to help separate impure functions from pure logic.
const isFunction = fn => fn && Object.prototype.toString.call(fn) === '[object Function]';
const isAsync = fn => fn && Object.prototype.toString.call(fn) === '[object AsyncFunction]';
const isPromise = p => p && Object.prototype.toString.call(p) === '[object Promise]';
const tap = f => x => {
f(x);
return x;
};
class Container {
constructor(fn) {
this.value = fn;
if (!isFunction(fn) && !isAsync(fn)) {
throw new TypeError(`Container expects a function, not a ${typeof fn}.`);
};
}
map(fn) {
if (!isFunction(fn) && !isAsync(fn)) {
throw new TypeError(`The map method expects a function, not a ${typeof fn}.`);
};
return new Container(
() => isPromise(this.value()) ?
this.value().then(fn) : fn(this.value())
)
}
run() {
return this.value();
}
};
const sayHello = () => 'Hello';
const addName = (name, str) => str + ' ' + name;
const container = new Container(sayHello);
const greet = container
.map(addName.bind(this, 'Joe Bloggs'))
.map(tap(console.log));
greet.run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment