UNPKG

bingo-functional-js

Version:

A port of the PHP bingo-functional library

95 lines (84 loc) 1.9 kB
const Monadic = require('../monad') const extend = require('../../../Algorithms/Collection/extend') const { isEmpty, isUndefined } = require('../../../Algorithms/Function') /** * Writer monad * @constructor * @param {function} action */ function Writer(action) { Monadic.call(this, action) /** * ap function * @param {Writer} writer * @returns {Writer} * @example * * Writer.of((x) => x ** 2, 'put fn').ap(Writer.of(2, 'put 2')) * // => [Writer] */ this.ap = function (writer) { return this.bind((transform) => writer.map(transform)) } /** * bind function * @param {function} transform * @returns {Writer} * @example * * writer(2, 'put 2').bind((x) => writer(x ** 2, 'square val')) * // => [Writer] */ this.bind = function (transform) { return new Writer(() => { const [res, out] = this.run() const [_res, _out] = transform(res).run() return [_res, extend(out, _out)] }) } /** * map function * @param {function} transform * @returns {Writer} * @example * * writer(2, 'put 2').map((x) => x ** 3) * // => [Writer] */ this.map = function (transform) { return new Writer(() => { const [res, out] = this.run() return [transform(res), out] }) } /** * run function * @returns {*} * @example * * writer('foo', 'put str').run() * // => ['foo', ['put str']] */ this.run = function () { return this.val() } } Writer.prototype = Object.create(Monadic.prototype) Writer.prototype.constructor = Monadic /** * of function * @param {*} result * @param {*} output * @returns {Writer} * @example * * Writer.of('foo', 'put foo') * // => [Writer] */ Writer.of = function (result, output) { return new Writer(() => [ result, isEmpty(output) || isUndefined(output) ? [] : [output], ]) } module.exports = Writer