Home Reference Source Repository

src/either.js

import { Monad } from "./monad";
import { equality } from "./services/equality";
/**
 * Class Either - represents computation with two possibilities.
 * @extends {Monad}
 */
export class Either extends Monad {
    /**
     * Creates an instance of class Either.
     * @param {function(v: any) => any} r - right function.
     * @param {function(v: any) => any} l - left function.
     */
    constructor(r, l) {
        super();
        this.r = r;
        this.l = l;
    }
    /**
     * Binds controller function and underlying value to the monad.
     * @method bind
     * @param {D<T>} f - controller function, after execution f(v) produce true (execute right func-n) or false (execute left func-n).
     * @param {any} v - underlying value for the monad.
     * @return {boolean | Pr<any> | Error}
     */
    bind(f, v) {
        this.uVal = v;
        try {
            switch (f(v)) {
                case true:
                    return this.r(v);
                case false:
                    return this.l(v);
                default:
                    return this.fail('Either.bind() - binding error');
            }
        }
        catch (e) {
            this.fail(`Either.bind().switch - ${e}`);
        }
    }
    /**
     * Extract result of left(v) computation.
     * @method left
     * @param {T} v - underlying value.
     * @return {Pr}
     */
    left(v) {
        return this.uVal ? equality(this.uVal, v) ? this.l(v) : this.fail('Either.left() - v have been binded with bind method') : this.l(v);
    }
    /**
     * Extract result of right(v) computation.
     * @method right
     * @param {T} v - underlying value.
     * @return {Pr}
     */
    right(v) {
        return this.uVal ? equality(this.uVal, v) ? this.r(v) : this.fail('Either.right() - v have been binded with bind method') : this.r(v);
    }
}
//Copyright (c) 2017 Alex Tranchenko. All rights reserved.