igogo
Version:
Fast Either and Maybe from Fantasy Land with Flow and TypeScript support
596 lines (452 loc) • 8.63 kB
JavaScript
/**
* igogo v1.8.2
* Fast Either and Maybe from Fantasy Land with Flow and TypeScript support
*/
import 'core-js/modules/es.symbol.description';
import 'core-js/modules/es.promise';
const getSet = keyName => {
const key = Symbol(keyName);
return [instance => instance[key], (instance, value) => instance[key] = value];
};
const next = () => ({
value: undefined,
done: true
});
const toEmptyIterator = () => {
const iterator = {
[Symbol.iterator]: () => iterator,
next
};
return iterator;
};
const toIterator = getValue => // eslint-disable-next-line no-shadow
function toIterator() {
let next$1 = () => {
next$1 = next;
return {
value: getValue(this),
done: false
};
};
const iterator = {
/* :: @@iterator: () => iterator, */
[Symbol.iterator]: () => iterator,
next: () => next$1()
};
return iterator;
};
class EitherRight {
constructor(value) {
setRight(this, value);
}
get isRight() {
return true;
}
get isLeft() {
return false;
}
/* :: +@@iterator: () => Iterator<R>; */
map(transform) {
return this.mapR(transform);
}
mapR(transform) {
return new EitherRight(transform(getRight(this)));
}
mapL() {
return this;
}
bimap(transformL, transformR) {
return this.mapR(transformR).mapL(transformL);
}
mapTo(value) {
return Right(value);
}
mapRTo(value) {
return Right(value);
}
mapLTo() {
return this;
}
bimapTo(left, right) {
return this.mapRTo(right).mapLTo(left);
}
chain(transform) {
return this.chainR(transform);
}
chainR(transform) {
return transform(getRight(this));
}
chainL() {
return this;
}
bichain(transformL, transformR) {
return transformR(getRight(this));
}
ap(either) {
return this.apR(either);
}
apR(either) {
return either.map(transform => transform(getRight(this)));
}
apL() {
return this;
}
biap(either) {
return this.apR(either);
}
alt() {
return this;
}
or() {
return this;
}
and(either) {
return either;
}
getOr() {
return getRight(this);
}
getOrElse() {
return getRight(this);
}
getLeftOr(value) {
return value;
}
getLeftOrElse(fn) {
return fn();
}
getRightOr() {
return getRight(this);
}
getRightOrElse() {
return getRight(this);
}
reduce(transform, or) {
return this.reduceR(transform, or);
}
reduceR(transform, or) {
return transform(or, getRight(this));
}
reduceL(transform, or) {
return or;
}
tap(call) {
return this.tapR(call);
}
tapR(call) {
call(getRight(this));
return this;
}
tapL() {
return this;
}
tapBoth(callL, callR) {
return this.tapR(callR);
}
swap() {
return new EitherLeft(getRight(this));
}
left() {
return this.toMaybeL();
}
right() {
return this.toMaybeR();
}
match(fromRight) {
return fromRight(getRight(this));
}
toMaybe() {
return this.toMaybeR();
}
toMaybeR() {
return Just(getRight(this));
}
toMaybeL() {
return nothing;
}
toMaybeLR() {
return this.toMaybe();
}
promise() {
return Promise.resolve(getRight(this));
}
fold(fromLeft, fromRight) {
return fromRight(getRight(this));
}
}
class EitherLeft {
constructor(value) {
setLeft(this, value);
}
get isRight() {
return false;
}
get isLeft() {
return true;
}
/* :: +@@iterator: () => Iterator<R>; */
map() {
return this;
}
mapR() {
return this;
}
mapL(transform) {
return new EitherLeft(transform(getLeft(this)));
}
bimap(transformL, transformR) {
return this.mapL(transformL).mapR(transformR);
}
mapTo() {
return this;
}
mapRTo() {
return this;
}
mapLTo(left) {
return new EitherLeft(left);
}
bimapTo(left, right) {
return this.mapLTo(left).mapRTo(right);
}
mapBoth(transformL, transformR) {
return this.bimap(transformL, transformR);
}
chain() {
return this;
}
chainR() {
return this;
}
chainL(transform) {
return transform(getLeft(this));
}
bichain(transformL) {
return transformL(getLeft(this));
}
ap() {
return this;
}
apR() {
return this;
}
apL(either) {
return either.mapL(transform => transform(getLeft(this)));
}
biap(either) {
return this.apL(either);
}
alt(either) {
return either;
}
or(either) {
return either;
}
and() {
return this;
}
getOr(value) {
return value;
}
getOrElse(fn) {
return fn(getLeft(this));
}
getLeftOr() {
return getLeft(this);
}
getLeftOrElse() {
return getLeft(this);
}
getRightOr(value) {
return value;
}
getRightOrElse(fn) {
return fn();
}
reduce(transform, or) {
return or;
}
reduceR(transform, or) {
return or;
}
reduceL(transform, or) {
return transform(or, getLeft(this));
}
tap() {
return this;
}
tapR() {
return this;
}
tapL(call) {
call(getLeft(this));
return this;
}
tapBoth(callL) {
return this.tapL(callL);
}
swap() {
return new EitherRight(getLeft(this));
}
left() {
return this.toMaybeL();
}
right() {
return this.toMaybeR();
}
match(fromRight, fromLeft) {
return fromLeft(getLeft(this));
}
toMaybe() {
return this.toMaybeR();
}
toMaybeR() {
return nothing;
}
toMaybeL() {
return Just(getLeft(this));
}
toMaybeLR() {
return this.toMaybeL();
}
promise() {
return Promise.reject(getLeft(this));
}
fold(fromLeft) {
return fromLeft(getLeft(this));
}
}
const [getRight, setRight] = getSet('right');
const [getLeft, setLeft] = getSet('left');
EitherRight.prototype[Symbol.iterator] = toIterator(getRight);
EitherLeft.prototype[Symbol.iterator] = toEmptyIterator;
const Right = right => new EitherRight(right);
const Left = left => new EitherLeft(left);
const ifElse = (condition, right, left) => condition ? Right(right) : Left(left);
class MaybeJust {
constructor(value) {
setValue(this, value);
}
get isJust() {
return true;
}
get isNothing() {
return false;
}
/* :: +@@iterator: () => Iterator<T>; */
map(transform) {
return Just(transform(getValue(this)));
}
mapTo(value) {
return Just(value);
}
ap(maybe) {
return maybe.map(transform => transform(getValue(this)));
}
chain(transform) {
return transform(getValue(this));
}
filter(predicate) {
const value = getValue(this);
return predicate(value) ? Just(value) : nothing;
}
tap(call) {
call(getValue(this));
return this;
}
and(maybe) {
return maybe;
}
or() {
return this;
}
alt() {
return this;
}
getOr() {
return getValue(this);
}
getOrElse() {
return getValue(this);
}
reduce(transform, or) {
return transform(or, getValue(this));
}
match(fromJust) {
return fromJust(getValue(this));
}
toEither() {
return Right(getValue(this));
}
promise() {
return Promise.resolve(getValue(this));
}
}
class MaybeNothing {
get isJust() {
return false;
}
get isNothing() {
return true;
}
/* :: +@@iterator: () => Iterator<T>; */
map() {
return nothing;
}
mapTo() {
return nothing;
}
ap() {
return nothing;
}
chain() {
return nothing;
}
filter() {
return nothing;
}
tap() {
return nothing;
}
and() {
return nothing;
}
or(maybe) {
return maybe;
}
alt(maybe) {
return maybe;
}
getOr(value) {
return value;
}
getOrElse(fn) {
return fn();
}
reduce(transform, or) {
return or;
}
match(fromJust, fromNothing) {
return fromNothing();
}
toEither(left) {
return Left(left);
}
promise(error) {
return Promise.reject(error);
}
}
const nothing = new MaybeNothing();
const [getValue, setValue] = getSet('value');
MaybeJust.prototype[Symbol.iterator] = toIterator(getValue);
MaybeNothing.prototype[Symbol.iterator] = toEmptyIterator;
const Just = value => new MaybeJust(value);
const Nothing = () => nothing;
const fromNullable = value => value == null ? nothing : Just(value);
const fromFalsy = value => !value ? nothing : Just(value);
const opt = fromNullable;
function when(predicate, value) {
const condition = typeof predicate == 'boolean' ? predicate : predicate(value);
return condition ? Just(value) : nothing;
}
export { Just, Left, Nothing, Right, fromFalsy, fromNullable, ifElse, nothing, opt, when };