ES6 is introducing classes to JavaScript. You can turn on the new features in Chrome by enabling chrome://flags/#enable-javascript-harmony or in v8 with v8 –harmony.
Functor = class Functor { constructor() { if (new.target === Functor) { throw new TypeError( 'Cannot construct Functor instances directly'); } if (typeof(this.map) !== 'function' || typeof(new.target.map) !== 'function') { throw new TypeError('Must provide static and member map.') } } }; // Base monad class Monad = class Monad extends Functor { constructor() { super(); if (new.target === Monad) { throw new TypeError( 'Cannot construct Monad instances directly'); } if (typeof(this.lift) !== 'function' || typeof(new.target.lift) !== 'function') { throw new TypeError('Must provide static and member lift.') } if (typeof(this.flatten) !== 'function' || typeof(new.target.flatten) !== 'function') { throw new TypeError('Must provide static and member flatten.') } } flatMap(f) { return this.map(f).flatten(); } static flatMap(f) { return (mx) => mx.flatMap(f); } }; // Promise monad P = class P extends Monad { // Constructor expects a promise to wrap. constructor(p) { super(); if (p && typeof(p.then) === 'function') { this.p = p; } else { throw new TypeError( 'Expected an object with a "then" method.'); } } static map(f) { return (px) => px.map(f); } map(f) { return new P(this.p.then(f)); } static lift(v) { return new this(new Promise((resolve) => resolve(v))); } lift() { return this.constructor.lift(this); } static flatten(ppv) { return new this(new Promise((resolve) => { return ppv.map((pv) => pv.map(resolve)) })); } flatten() { return this.constructor.flatten(this); } }; // XHR + Promise XHRP = (url) => new P(new Promise((resolve) => { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = () => { if (xhr.readyState == XMLHttpRequest.DONE) { if (xhr.status == 200) { resolve(xhr.responseText); } } }; xhr.open('GET', url, true); xhr.send(); })); // Search Google for your ip address XHRP('http://jsonip.com').flatMap((json) => XHRP('http://google.com/search?' + JSON.parse(json).ip).map((results) => console.log(results))); // New experimental GlobalFetch already returns promise if (GlobalFetch) { GFP = (url) => new P(GlobalFetch.fetch(url)); // Search Google for your ip address GFP('http://jsonip.com').flatMap((json) => GFP('http://google.com/search?' + JSON.parse(json).ip).map((results) => console.log(results))); } // setTimeout + Promise DelayP = (value, delay) => new P(new Promise((resolve) => setTimeout(() => resolve(value), delay))); DelayP(1, 1000).flatMap((v) => // Runs at t=1 sec, v = 1 DelayP(2+v, 2000).flatMap((w) => // Runs at t=3 sec, w = 3 DelayP(3+v+w, 3000).map((x) => // Runs at t=6 sec, x = 7 // Logs 15 console.log(4+v+w+x)))); DelayP(1, 1000) // Runs at t=1 sec, v=1 .map((v) => 2+v) // Runs at t=1 sec, w=3 .map((w) => 3+w) // Runs at t=1 sec, x=6 // Logs 10 .map((x) => console.log(4+x));
Leave a comment