@fpjs/overture
Version:
A Javascript prelude
87 lines (75 loc) • 2.32 kB
JavaScript
// 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([])
});
};