Asynchronous functional javascript using either-async-01

https://github.com/eu81273/jsfiddle-console

by dimitrs_papadimitriou

HTML

<script src="https://rawgit.com/eu81273/jsfiddle-console/master/console.js"></script>

JavaScript

const ok = (v) => ({
    v: v,
    map: f => ok(f(v)),
    bind: f => f(v),
    cata: (alg) => alg.ok(v),
    traverse: (TyperRep, f) => TyperRep(ok).app(f(v))
  });

  const error = (v) => ({
    v: v,
    map: () => error(v),
    bind: () => error(v),
    cata: (alg) => alg.error(v),
    traverse: (TyperRep, f) => TyperRep(error).app(f(v))
  });

  var safeTry = (f) => {
    try {
      return ok(f());
    } catch (e) {
      return error(e);
    }
  }

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

  const id = x => x;
  const idM = x => ok(x);

  const EitherAsync = (actions, mappings) => ({

    map: (f) => EitherAsync(actions, {
      resolve: compose(f, mappings.resolve),
      reject: mappings.reject,
    }),

    mapError: f => EitherAsync(actions, {
      resolve: mappings.resolve,
      reject: compose(f, mappings.reject)
    }),

    bimap: (f, g) => EitherAsync(actions, {
      resolve: compose(f, mappings.resolve),
      reject: compose(g, mappings.reject)
    }),

    app: fv => EitherAsync((resolve, reject) => actions(f => fv.map(compose(f, mappings.reject)).cata({
      ok: resolve,
      error: reject
    }), reject), mappings),

    bind: f => EitherAsync((resolve, reject) => actions(x => f(mappings.resolve(x)).cata({
      ok: resolve,
      error: reject
    }), reject), mappings),

    cata: alg => actions(compose(alg.ok, mappings.resolve), compose(alg.error, mappings.reject)),

    toPromise: () => new Promise((resolve, reject) => actions(compose(resolve, mappings.resolve), compose(reject, mappings.reject))),
    toEither: () => EitherAsync(actions, mappings),
    parallelBind: () => { }
  });

  EitherAsync.of = (actions) => EitherAsync(actions, {
    resolve: id,
    reject: id,
    chain: idM
  });

  EitherAsync.resolve = x => EitherAsync((resolve) => resolve(x), {
    resolve: id,
    reject: id,
    chain: idM
  });

  Promise.prototype.toEither = function () {
    return EitherAsync((resolve, reject) =>...