UNPKG

monads-co

Version:

An implementation of Haskell's type classes in TS

163 lines 4.23 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Maybe = exports.None = exports.Some = exports.Optional = void 0; const Monad_1 = require("./Monad"); class Optional extends Monad_1.Monad { _success; _value; constructor(_success, _value) { super(); this._success = _success; this._value = _value; } /** * Used to wrap a function that can potentially return null or undefined in a safe wrapper * ```ts * const safeQuerySelector = Optional.wrap(document.querySelector) * ``` * @param fn */ static wrap(fn) { return (...args) => { const out = fn(...args); if (out === undefined || out === null) { return None(); } else { return Some(out); } }; } /** * If a value is held, this uses the mapping function to transform it, and returns Optional<New Value> * otherwise, it returns None() * @param mapping */ map(mapping) { if (this._success) { return Some(mapping(this._value)); } else { return None(); } } amap(mapping) { if (this._success) { if (mapping._success) { return Some(mapping._value(this._value)); } return None(); } return None(); } pure(value) { return Some(value); } /** * If a value is held the mapping is preformed on it, otherwise None() is returned. 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 None(); } // Result specific methods /** * Returns the value is defined, otherwise it returns `defaultValue` * @param defaultValue */ or(defaultValue) { if (this._success) { return this._value; } return defaultValue; } /** * If None() replace it with a value * @param mapping */ catch(mapping) { if (this._success) { return Some(this._value); } return Some(mapping()); } /** * If None() replaces it with the result of the mapping * @param mapping */ catchThen(mapping) { if (this._success) { return Some(this._value); } return mapping(); } /** * Returns the value if Some(), otherwise it throws a reference error. * This is the nuclear option, `.or(default)` should be preferred. */ unwrap() { if (this._success) { return this._value; } // Kaboom, functional land just died :( throw new ReferenceError("When Optional<T> was unwrapped, no value was found"); } } exports.Optional = Optional; /** * Used to construct Some value, for example: * * @example * ```ts * // Gets all but the start of the string; IE "string" -> "tring" * function getStringTail(input: string): Optional<string> { * if (input.length <= 1) { * return None() * } else { * return Some(input.slice(1)) * } * } * ``` * @param value */ function Some(value) { return new Optional(true, value); } exports.Some = Some; /** * Used to construct Some value, for example: * * @example * ```ts * // Gets all but the start of the string; IE "string" -> "tring" * function getStringTail(input: string): Optional<string> { * if (input.length <= 1) { * return None() * } else { * return Some(input.slice(1)) * } * } * ``` */ function None() { return new Optional(false, null); } exports.None = None; /** * Like Some() or None() but it doesn't mind if you give it a value or not. * @param value */ function Maybe(value) { if (value) { return Some(value); } else { return None(); } } exports.Maybe = Maybe; //# sourceMappingURL=Optional.js.map