UNPKG

maybetyped

Version:

Well-typed functional Maybe monad

212 lines (198 loc) 6.88 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); // TODO: remove this if fantasy-land exports own types var map = 'fantasy-land/map'; var ap = 'fantasy-land/ap'; var of = 'fantasy-land/of'; var chain = 'fantasy-land/chain'; var _a, _b, _c; var binder = function (context, f) { return f.bind(context); }; // tslint:disable-line ban-types var isNothing = function (thing) { return thing === undefined || thing === null; }; var Maybe = /** @class */ (function () { function Maybe(value) { var _this = this; this.value = value; this[_a] = binder(this, this.map); this[_b] = binder(this, this.flatMap); this[_c] = function (m) { return m.flatMap(function (f) { return _this.map(f); }); }; } Maybe.prototype.isNothing = function () { return isNothing(this.value); }; return Maybe; }()); _a = map, _b = chain, _c = ap; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var Some = /** @class */ (function (_super) { __extends(Some, _super); function Some() { return _super !== null && _super.apply(this, arguments) || this; } Some.some = function (thing) { return new Some(thing); }; Some.prototype.expect = function () { return this.value; }; Some.prototype.caseOf = function (funcs) { return funcs.some ? maybe(funcs.some(this.value)) : none(); }; Some.prototype.map = function (f) { return maybe(f(this.value)); }; Some.prototype.tap = function (f) { f(this.value); return this; }; Some.prototype.flatMap = function (f) { return f(this.value); }; Some.prototype.orElse = function (def) { return this.value; }; Some.prototype.or = function (other) { return this; }; Some.prototype.eq = function (other) { var _this = this; return other.map(function (v) { return v === _this.value; }) .orElse(false); }; Some.prototype.join = function (f, other) { return this.flatMap(function (x) { return other.map(function (y) { return f(x, y); }); }); }; Some.prototype.asNullable = function () { return this.value; }; return Some; }(Maybe)); var some = Some.some; var isNoArgFunc = function (x) { return typeof x === "function" && x.length === 0; }; var invokeFunc = function (funcOrT) { if (isNoArgFunc(funcOrT)) { return funcOrT(); } return funcOrT; }; var None = /** @class */ (function (_super) { __extends(None, _super); function None() { return _super.call(this, null) || this; } None.none = function () { return new None(); }; None.prototype.expect = function (msg) { if (msg instanceof Error) throw msg; throw new Error(msg || 'Expected Maybe to contain non-null value'); }; None.prototype.caseOf = function (funcs) { return funcs.none ? maybe(funcs.none()) : this; }; None.prototype.map = function () { return this; }; None.prototype.tap = function () { return this; }; None.prototype.flatMap = function () { return this; }; None.prototype.orElse = function (def) { return invokeFunc(def); }; None.prototype.or = function (other) { return invokeFunc(other); }; None.prototype.eq = function (other) { return other instanceof None; }; None.prototype.join = function (f, other) { return this; }; None.prototype.asNullable = function () { return null; }; return None; }(Maybe)); var _noneSingleton = None.none(); var none = function () { return _noneSingleton; }; var isPromise = function (x) { return typeof x.then === 'function'; }; var getMap = function (x) { if (isPromise(x)) return x.then.bind(x); return x.map.bind(x); }; var MaybeT = /** @class */ (function () { function MaybeT(value) { this.value = value; } MaybeT.maybeT = function (monad) { return new MaybeT(monad); }; MaybeT.prototype.map = function (f) { var map = getMap(this.value); return new MaybeT(map(function (inner) { return maybe(inner) .map(f) .asNullable(); })); }; MaybeT.prototype.caseOf = function (matcher) { var map = getMap(this.value); return new MaybeT(map(function (inner) { return maybe(inner) .caseOf(matcher) .asNullable(); })); }; MaybeT.prototype.orElse = function (def) { var map = getMap(this.value); return map(function (inner) { return maybe(inner) .orElse(def); }); }; MaybeT.prototype.asNullable = function () { return this.value; }; MaybeT.prototype.asType = function (c) { if (!(this.value instanceof c)) throw new Error("Expected value to be instance of monad " + c.name); return this.value; }; return MaybeT; }()); var maybeT = MaybeT.maybeT; var maybe = function (value) { return isNothing(value) ? none() : some(value); }; // gotta do this here to get around circular imports Maybe.of = maybe; Maybe[of] = maybe; exports.MaybeT = MaybeT; exports.default = Maybe; exports.maybe = maybe; exports.maybeT = maybeT; exports.none = none; exports.some = some;