/**
* Either monad, parent of `Left` and `Right`.
* Used for `Right` instance creation.
*/
class Either {
constructor(x) {
this.value = x;
}
static of(x) {
return new Right(x);
}
}
/**
* Left value of the Either monad.
* Has noop implementations.
*/
class Left extends Either {
get isLeft() {
return true;
}
get isRight() {
return false;
}
static of(x) {
throw new Error(
"`of` called on class Left (value) instead of Either (type)"
);
}
equals(other) {
return other instanceof Left && this.value === other.value;
}
map() {
return this;
}
ap() {
return this;
}
chain() {
return this;
}
join() {
return this;
}
sequence(of) {
return of(this);
}
traverse(of, fn) {
return of(this);
}
}
/**
* Right value of the Either monad.
*/
class Right extends Either {
get isLeft() {
return false;
}
get isRight() {
return true;
}
static of(x) {
throw new Error(
"`of` called on class Right (value) instead of Either (type)"
);
}
equals(other) {
return other instanceof Right && this.value === other.value;
}
map(fn) {
return Either.of(fn(this.value));
}
ap(f) {
return f.map(this.value);
}
chain(fn) {
return this.map(fn).join();
}
join() {
return this.value;
}
sequence(of) {
return this.traverse(of, (x) => x);
}
traverse(of, fn) {
return fn(this.value).map(Either.of);
}
}
export { Left, Right, Either };