Promise Composition

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

by dimitrs_papadimitriou

HTML

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

JavaScript

////Copyright (c) 2019 dimitris papadimitriou

  Promise.prototype.map = function(mapping) {
    var initialPromise = this;
    return new Promise(function(resolve) {
      initialPromise.then(result => resolve(mapping(result)))
    });
  }

  const ok = (v) => ({
    v: v,
    map: (f) => ok(f(v)), 
    cata: (alg) => alg.ok(v),  
  });
  
  const error = (v) => ({
    v: v,
    map: () => error(v), 
    cata: (alg) => alg.error(v),  
  });

  var EitherCoyoAsync = function(actions, g) {
    this.g = g; 
    
    this.map = (f) => new EitherCoyoAsync(actions, x => f(this.g(x))); 
    
    this.bind = f =>{  
      var initialPromise = this;
      return new EitherCoyoAsync(function(resolve, reject) {
       actions(x => f(initialPromise.lower(x)).cata({ok:resolve,error:reject}) , x=>reject(x))
      }, x => x);
    }

    this.cata = alg => actions(x => alg.ok(this.lower(x)), alg.error); 

    this.lower = (v) => this.g(v);
  }

  Promise.prototype.toEither = function() {
    var initialPromise = this;
    var either = new EitherCoyoAsync(function(resolve, reject) {
      initialPromise.then(resolve).catch(reject)
    }, x => x);
    return either;
  }
 
  fetch("https://api.github.com/users")
   .map(response => response.json()) //this is promise map  
   .toEither() 
   .map(users=>users.map(u=>u.login))  
   .map(users=>users[0])  
   .bind(u=> ok("user login is :"+u)) 

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