Package Exports
- js-monadic
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (js-monadic) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
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' }