js-monadic
v0.1.7
Published
Monad with do notation in Javascript, using ES6 generators.
Downloads
7
Maintainers
Readme
js-monadic
Monad with do notation in Javascript, using ES6 generators.
Installing
Using npm:
$ npm install js-monadic
Using yarn:
$ yarn add js-monadic
Using unpkg CDN:
<script src="https://unpkg.com/js-monadic/umd/js-monadic.min.js"></script>
Usage
const Monad = require('js-monadic')
// Unit/Return function of the monad
function unit(v) {
// ...
}
// Bind function of the monad
function bind(v, f) {
// ...
}
const MyMonad = Monad(unit, bind)
// Same as calling unit(...)
const val = MyMonad(/* ... */)
MyMonad.do(function*() {
const foo = yield MyMonad(/* ... */)
// ...
}())
Example
Option / Maybe
// type Option<T> = { some: T } | null
const Option = Monad(
(value) => value === null ? null : { some: value },
(option, fn) => option === null ? null : fn(option.some)
)
const foo = Option.do(function*() {
const a = yield Option(1) // a = 1
const b = yield Option(2) // b = 2
const c = yield Option(3) // c = 3
return Option(a + b + c)
}())
// foo = { some: 6 }
const bar = Option.do(function*() {
const a = yield Option(1) // a = 1
const b = yield Option(null)
// will not reach here at all because the function in
// the second argument of "bind" was not called when
// evaluating Option(null), therefore the chain stops here
const c = yield Option(3)
return Option(a + b + c)
}())
// bar = null
Result / Either
// type Result<T> = { ok: T } | { error: Error }
const Result = Monad(
(value) => value instanceof Error ? { error: value } : { ok: value },
(result, fn) => 'error' in result ? result : fn(result.ok)
)
const foo = Result.do(function*() {
const a = yield Result(1) // a = 1
const b = yield Result(2) // b = 2
return Result(a + b)
}())
// foo = { ok: 3 }
const bar = Result.do(function*() {
const a = yield Result(1) // a = 1
const b = yield Result(new Error('Bad object'))
// will not reach here
return Result(a + b)
}())
// bar = { error: Error('Bad object') }
Promise
// type Future<T> = Promise<T>
const Future = Monad(
(value) => Promsie.resolve(value),
(result, fn) => result.then(fn)
)
const foo = Future.do(function*() {
const a = yield Promise.resolve(1) // a = 1
const b = yield Promise.resolve(2) // b = 2
return Promise.resolve(a + b)
}())
// foo = Promise { 3 }
const bar = Future.do(function*() {
const a = yield Promise.resolve(1) // a = 1
const b = yield Promise.reject('Bad object')
// will not reach here
return Promise.resolve(a + b)
}())
// bar = Promise { <rejected> 'Bad object' }