UNPKG

monads-co

Version:

An implementation of Haskell's type classes in TS

166 lines 4.39 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Err = exports.Ok = exports.Result = void 0; const Monad_1 = require("./Monad"); const Optional_1 = require("./Optional"); class Result extends Monad_1.Monad { _success; _value; constructor(_success, _value) { super(); this._success = _success; this._value = _value; } /** * Used to wrap a potential error throwing function into a safe Result wrapped function. Usage looks like: * ```ts * const safeJsonParse = Result.wrap<typeof JSON.parse, SyntaxError>(JSON.parse) * ``` * @param fn */ static wrap(fn) { return (...args) => { try { return Ok(fn(...args)); } catch (e) { return Err(e); } }; } /** * If Ok, this uses the mapping function to transform Value to a new Value, and returns Result<New Value, ErrorT> * otherwise it propagates the ErrorT. * @param mapping */ map(mapping) { if (this._success) { return Ok(mapping(this._value)); } else { return Err(this._value); } } amap(mapping) { if (this._success) { if (mapping._success) { return Ok(mapping._value(this._value)); } } if (!mapping._success) { return Err(mapping._value); } return Err(this._value); } pure(value) { return Ok(value); } /** * If Ok, the mapping of ValueT to a Result is run, otherwise the Error is propagated. If you want to just transform * ValueT to a new Value, use `.map` * @param mapping */ then(mapping) { if (this._success) { return mapping(this._value); } return Err(this._value); } // Result specific methods /** * Returns the ValueT if Ok, otherwise it returns `defaultValue` * @param defaultValue */ or(defaultValue) { if (this._success) { return this._value; } return defaultValue; } /** * If Err this runs the mapping from ErrorT => ValueT, otherwise it returns a new Result containing ValueT * @param mapping */ catch(mapping) { if (this._success) { return Ok(this._value); } return Ok(mapping(this._value)); } /** * If Err this runs the mapping from ErrorT => Result<ValueT, NewErrorT>, otherwise it returns a new Result containing * ValueT * @param mapping */ catchThen(mapping) { if (this._success) { return Ok(this._value); } return mapping(this._value); } /** * Returns the ValueT if Ok, otherwise it throws ErrorT. This is the nuclear option, `.or(default)` should be preferred. */ unwrap() { if (this._success) { return this._value; } // Kaboom, functional land just died :( throw this._value; } /** * Converts a Result<ValueT, ErrorT> to an Optional<ValueT> */ toOptional() { if (this._success) { return (0, Optional_1.Some)(this._value); } else { return (0, Optional_1.None)(); } } } exports.Result = Result; /** * Used to construct an Ok value, for example: * * @example * ```ts * type ErrorMessage = string * * function safeDivide(a: number, b: number): Result<number, ErrorMessage> { * if (b === 0) { * return Err("Can't divide by zero") * } else { * return Ok(a / b) * } * } * ``` * @param value */ function Ok(value) { return new Result(true, value); } exports.Ok = Ok; /** * Used to construct an Err value, for example: * * @example * ```ts * type ErrorMessage = string * * function safeDivide(a: number, b: number): Result<number, ErrorMessage> { * if (b === 0) { * return Err("Can't divide by zero") * } else { * return Ok(a / b) * } * } * ``` * @param value */ function Err(value) { return new Result(false, value); } exports.Err = Err; //# sourceMappingURL=Result.js.map