JSFiddle - React, Tailwind, and code Playground

by dimitrs_papadimitriou

JavaScript

(function () {

    Promise.prototype.map = function (f) {
      return (self => new Promise(function (resolve) {
        self.then(result => resolve(f(result)))
      }))(this);
    }

    const compose = (...fns) => x => fns.reduceRight((y, f) => f(y), x);

    var id = x => x;

    var EitherAsync = (actions, fOk, fError) => ({
      map: f => EitherAsync(actions, compose(f, fOk), fError),
      mapError: f => EitherAsync(actions, fOk, compose(f, fError)),
      bimap: (f, g) => EitherAsync(actions, compose(f, fOk), compose(g, fError)),
      ap: fv => EitherAsync((resolve, reject) => actions(f => fv.map(compose(f, fOk)).cata({
        ok: resolve,
        error: reject
      }), reject), fOk, fError),

      bind: f => EitherAsync((resolve, reject) => actions(x => f(fOk(x)).cata({
        ok: resolve,
        error: reject
      }), reject), id, id),
      cata: alg => actions(compose(alg.ok, fOk), compose(alg.error, fError)),
    });

    Promise.prototype.toEither = function () {
      return EitherAsync((resolve, reject) => this.then(resolve).catch(reject), id, id);
    }

  }())
 
  var r = Promise.resolve(x => x + 5)
    .toEither()
    .ap(Promise.resolve(7).toEither())
    .bind(x => new Promise(resolve => resolve(x))
      .map(x => x + 3).toEither())
    .bimap(x => x + 3, x => 0)


  setTimeout(() => {
    r.cata({
      ok: v => console.log(v),
      error: v => console.log("left" + v)
    });
  }, 1000)













  // var r = Promise.resolve(5)
  //   .map(x => x)
  //   .toEither()
  //   .bind(x => new Promise(resolve=>setTimeout(() => {  console.log("2000");resolve(5+x)},2000)).map(x => x).toEither())


  // console.log("_")
  // setTimeout(() => {
  //   console.log("1000")
  //   r.cata({
  //     ok: v => console.log(v),
  //     error: v => console.log("left" + v)
  //   });
  // }, 1000)