UNPKG

@fpjs/overture

Version:
87 lines (75 loc) 2.32 kB
// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. /** * Maybe represents an optional value. */ import {constant, id, type} from "@fpjs/overture/base"; import {map} from "@fpjs/overture/algebras/functor"; import {equals} from "@fpjs/overture/algebras/setoid"; import {lte} from "@fpjs/overture/algebras/ord"; /** Maybe data type */ export const Maybe = { '@@type': 'Maybe', }; const self = function() { return this; }; ///:: Maybe a export const Nothing = { '@@type': 'Maybe', '@@name': 'Nothing', 'constructor': Maybe, 'fantasy-land/map': self, 'fantasy-land/ap': self, 'fantasy-land/chain': self, 'fantasy-land/reduce': (_, z) => z, 'fantasy-land/equals': (y) => y.caseOf({ 'Nothing': constant (true), 'Just': constant (false), }), 'fantasy-land/lte': (y) => y.caseOf({ 'Nothing': constant (true), 'Just': lte (x), }), 'caseOf': (cases) => cases['Nothing'](), }; ///:: a -> Maybe a export const Just = (x) => ({ '@@type': 'Maybe', '@@name': 'Just', 'constructor': Maybe, 'fantasy-land/map': (f) => Just (f (x)), 'fantasy-land/ap': map ((f) => f(x)), 'fantasy-land/chain': (f) => f (x), 'fantasy-land/reduce': (f, z) => f (z, x), 'fantasy-land/equals': (y) => y.caseOf({ 'Nothing': constant (true), 'Just': equals (x), }), 'fantasy-land/lte': (y) => y.caseOf({ 'Nothing': constant (true), 'Just': lte (x), }), 'caseOf': (cases) => cases['Just'](x), }); Maybe['fantasy-land/of'] = Just; /** Extract the value from Just, or return the default value for Nothing. */ ///:: a -> Maybe a -> a export const fromMaybe = (def) => (x) => { if (type (x) !== 'Maybe') { throw TypeError(`${type (x)} is not Maybe.`); } return x.caseOf({ 'Just': id, 'Nothing': constant(def) }); }; export const toMaybe = (x) => (x != null) ? Just (x) : Nothing; export const maybeToArray = (x) => { if (type (x) !== 'Maybe') { throw TypeError(`${type (x)} is not Maybe.`); } return x.caseOf({ 'Just': (x) => [x], 'Nothing': constant([]) }); };