scats
Version:
Useful scala classes in typescript
248 lines (247 loc) • 5.72 kB
JavaScript
import { none, some } from './option.js';
import { Collection, Nil } from './collection.js';
import { failure, success } from './try.js';
import { toErrorConversion } from './util.js';
export class Either {
get isRight() {
return !this.isLeft;
}
get left() {
return new Either.LeftProjection(this);
}
fold(fa, fb) {
return this.match({
right: v => fb(v),
left: e => fa(e)
});
}
get swap() {
return this.match({
right: v => left(v),
left: e => right(e)
});
}
foreach(f) {
this.match({
right: b => f(b),
left: () => {
}
});
}
getOrElse(or) {
return this.match({
right: b => b,
left: () => or()
});
}
getOrElseValue(or) {
return this.match({
right: b => b,
left: () => or
});
}
orElse(or) {
return this.match({
right: () => this,
left: () => or()
});
}
orElseValue(or) {
return this.match({
right: () => this,
left: () => or
});
}
contains(elem) {
return this.match({
right: b => elem === b,
left: () => false
});
}
forall(f) {
return this.match({
right: b => f(b),
left: () => true
});
}
exists(p) {
return this.match({
right: b => p(b),
left: () => false
});
}
flatMap(f) {
return this.match({
right: v => f(v),
left: () => this
});
}
flatMapPromise(f) {
return this.match({
right: v => f(v),
left: () => Promise.resolve(this)
});
}
map(f) {
return this.match({
right: v => right(f(v)),
left: () => this
});
}
async mapPromise(f) {
return this.match({
right: async (v) => right(await f(v)),
left: () => Promise.resolve(this)
});
}
filterOrElse(p, zero) {
return this.match({
right: (v) => p(v) ? this : left(zero()),
left: () => this,
});
}
filterOrElseValue(p, zero) {
return this.match({
right: (v) => p(v) ? this : left(zero),
left: () => this,
});
}
get toCollection() {
return this.match({
right: v => Collection.of(v),
left: () => Collection.empty
});
}
get toOption() {
return this.match({
right: v => some(v),
left: () => none
});
}
toTry(toError = toErrorConversion) {
return this.match({
right: (b) => success(b),
left: (e) => failure(toError(e))
});
}
}
export class Left extends Either {
error;
constructor(error) {
super();
this.error = error;
}
match(matcher) {
return matcher.left(this.error);
}
get isLeft() {
return true;
}
withRight() {
return this;
}
}
export class Right extends Either {
value;
constructor(value) {
super();
this.value = value;
}
match(matcher) {
return matcher.right(this.value);
}
get isLeft() {
return false;
}
withLeft() {
return this;
}
}
(function (Either) {
class LeftProjection {
e;
constructor(e) {
this.e = e;
}
mapPromise(f) {
return this.e.match({
left: async (v) => left(await f(v)),
right: () => Promise.resolve(this.e)
});
}
flatMapPromise(f) {
return this.e.match({
left: v => f(v),
right: () => Promise.resolve(this.e)
});
}
foreach(f) {
this.e.match({
left: l => f(l),
right: () => {
}
});
}
getOrElse(or) {
return this.e.match({
left: a => a,
right: or
});
}
getOrElseValue(or) {
return this.e.match({
left: a => a,
right: () => or
});
}
forall(p) {
return this.e.match({
left: (a) => p(a),
right: () => true
});
}
exists(p) {
return this.e.match({
left: (a) => p(a),
right: () => false
});
}
flatMap(f) {
return this.e.match({
left: (a) => f(a),
right: () => this.e
});
}
map(f) {
return this.e.match({
left: a => left(f(a)),
right: () => this.e
});
}
filterToOption(p) {
return this.e.match({
left: l => p(l) ? some(this.e) : none,
right: () => none
});
}
get toCollection() {
return this.e.match({
left: l => Collection.of(l),
right: () => Nil
});
}
get toOption() {
return this.e.match({
left: l => some(l),
right: () => none
});
}
}
Either.LeftProjection = LeftProjection;
})(Either || (Either = {}));
export function right(value) {
return new Right(value);
}
export function left(value) {
return new Left(value);
}