scats
Version:
Useful scala classes in typescript
213 lines (212 loc) • 4.33 kB
JavaScript
import { none, some } from './option.js';
import { left, right } from './either.js';
import { identity } from './util.js';
export class TryLike {
async mapPromise(f) {
return this.match({
success: r => Try.promise(() => f(r)),
failure: () => Promise.resolve(this)
});
}
flatMapPromise(f) {
return this.match({
success: r => f(r),
failure: () => Promise.resolve(this)
});
}
foreach(f) {
if (this.isSuccess) {
f(this.get);
}
}
tapFailure(f) {
return this.match({
success: () => this,
failure: e => {
try {
f(e);
return this;
}
catch (ex) {
return failure(ex);
}
}
});
}
toEitherWithLeft(f) {
return this.match({
success: r => right(r),
failure: e => left(f(e))
});
}
}
export class Success extends TryLike {
result;
isSuccess = true;
isFailure = false;
constructor(result) {
super();
this.result = result;
}
get toOption() {
return some(this.result);
}
get toEither() {
return right(this.result);
}
map(f) {
return success(f(this.result));
}
get get() {
return this.result;
}
getOrElse(_) {
return this.result;
}
getOrElseValue(_) {
return this.result;
}
orElse(_) {
return this;
}
match(matcher) {
return matcher.success(this.result);
}
flatMap(f) {
try {
return f(this.result);
}
catch (e) {
return failure(e);
}
}
filter(p) {
try {
if (p(this.result)) {
return this;
}
else {
return failure(new Error('Predicate does not hold for ' + this.result));
}
}
catch (e) {
return failure(e);
}
}
get failed() {
return failure(new Error('Success.failed'));
}
fold(fa, fb) {
try {
return fb(this.result);
}
catch (e) {
return fa(e);
}
}
recover(_) {
return this;
}
recoverWith(_) {
return this;
}
transform(s, _) {
return this.flatMap(s);
}
}
export class Failure extends TryLike {
error;
isSuccess = false;
isFailure = true;
constructor(error) {
super();
this.error = error;
}
get toOption() {
return none;
}
get toEither() {
return left(this.error);
}
map(_) {
return this;
}
get get() {
throw this.error;
}
getOrElse(value) {
return value();
}
getOrElseValue(value) {
return value;
}
orElse(value) {
try {
return value();
}
catch (e) {
return failure(e);
}
}
match(matcher) {
return matcher.failure(this.error);
}
flatMap(_) {
return this;
}
filter(_) {
return this;
}
get failed() {
return success(this.error);
}
fold(fa, _) {
return fa(this.error);
}
recover(f) {
try {
return success(f(this.error));
}
catch (ex) {
return failure(ex);
}
}
recoverWith(f) {
return this.transform(identity, f);
}
transform(s, f) {
try {
return f(this.error);
}
catch (ex) {
return failure(ex);
}
}
}
export function Try(block) {
try {
return new Success(block());
}
catch (e) {
return new Failure(e);
}
}
(function (Try) {
function promise(block) {
try {
return block()
.then(res => new Success(res))
.catch(e => new Failure(e));
}
catch (e) {
return Promise.resolve(new Failure(e));
}
}
Try.promise = promise;
})(Try || (Try = {}));
export function success(x) {
return new Success(x);
}
export function failure(x) {
return new Failure(x);
}