C. Scott Ananian (2014-02-14T02:38:52.000Z)
And, if you like the division between `then` and `chain`:

class MonadicPromise extends Promise {
    constructor(exec) {
        class MP extends MonadicPromise {
            constructor(exec) {
                Promise.call(this, (f,r) => exec( v => f([v]), r));
            }
        }
        return new MP(exec);
    }
    chain(f, r) {
        return super.then(v => f(v[0]), r);
    }
    then(f, r) {
        return super.then(v => Promise.resolve(v[0]).then(f, r), r);
    }
    // See https://github.com/domenic/promises-unwrapping/issues/95
    resolve(v) {
        return new MonadicPromise(function(r) { r(v); });
    }
};

You can put MonadicPromises in your async maps if you wish to be able
to use chain on the values; otherwise they are indistinguishable from
standard promises.  There is a bit of extra cost for
MonadicPromise.resolve, since it always creates a wrapper -- but the
common-case non-monadic Promise doesn't need to pay for this.
  --scott
forbes at lindesay.co.uk (2014-02-14T10:33:33.243Z)
And, if you like the division between `then` and `chain`:

```js
class MonadicPromise extends Promise {
    constructor(exec) {
        class MP extends MonadicPromise {
            constructor(exec) {
                Promise.call(this, (f,r) => exec( v => f([v]), r));
            }
        }
        return new MP(exec);
    }
    chain(f, r) {
        return super.then(v => f(v[0]), r);
    }
    then(f, r) {
        return super.then(v => Promise.resolve(v[0]).then(f, r), r);
    }
    // See https://github.com/domenic/promises-unwrapping/issues/95
    resolve(v) {
        return new MonadicPromise(function(r) { r(v); });
    }
};
```

You can put MonadicPromises in your async maps if you wish to be able
to use chain on the values; otherwise they are indistinguishable from
standard promises.  There is a bit of extra cost for
`MonadicPromise.resolve`, since it always creates a wrapper -- but the
common-case non-monadic Promise doesn't need to pay for this.