JSFiddle - React, Tailwind, and code Playground

JavaScript

const Either = {};

Either.fromPromise = promise => {
  return promise.then(Either.right, Either.left);
};

Either.left = Either.failure = x => ({
  map: f => Either.left(x), //no-op: no mapping if "left" value
  fold: (l, r) => l(x), //apply "left" function to extract error value
  inspect: () => `Either.left(${x})`, //for debugging
  andThen: f => Either.left(x), //or flatMap or chain or join: Left(Left(x)) -> Left(x)
  isLeft: () => true,
  isRight: () => false,
  dump: () => x, //for debugging
});

Either.right = Either.success = x => ({
  map: f => Either.right(f(x)), //map only if "right"
  fold: (l, r) => r(x), //apply "right" function to extract success value
  inspect: () => `Either.right(${x})`, //for debugging
  andThen: f => f(x), //or flatMap or chain or join: Right(Right(x)) -> Right(x)
  isLeft: () => false,
  isRight: () => true,
  dump: () => x, //for debugging
});

Promise.prototype.andThenE = function(andThen) {
  return this.then(p => {
    return p.fold(
      e => Promise.reject(Either.left(e)),
      s => andThen(s),
    );
  }).catch(c => c);
};

const f = async (arr) => {
  return Either.right(arr.map(x => x+1));
};


const main = async () => {
	const out = await Either.fromPromise(Promise.resolve([1])).andThenE(f).andThenE(f);
  console.log('out.isRight():', out.isRight());
  console.log('res', out.dump());
}

main();