Created
October 15, 2019 20:46
-
-
Save BretCameron/0086bff21d5019824115aa2818ccbf69 to your computer and use it in GitHub Desktop.
An example container used for functional programming, to help separate impure functions from pure logic.
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
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