C. Scott Ananian (2014-02-13T23:32:09.000Z)
For your consideration, here is an implementation of Monadic Promises,
as a Promise subclass:

(This version is inexpertly hand-rewritten into ES6; see
https://gist.github.com/cscott/b1966d485807d9a8cc39 for an ES5 version
which has been tested to work against
https://github.com/paulmillr/es6-shim/pull/215)

--- begin monadic.js ---
class MonadicPromise extends Promise {
    constructor(exec) {
        // the promise constructor needs to be new each time,
        // in order to thwart the optimization in Promise.resolve
        // (formerly Promise.cast)
        class MP extends MonadicPromise {
            constructor(exec) {
                Promise.call(this, (f,r) => exec( v => f([v]), r));
            }
        }
        return new MP(exec);
    },
    then(f, r) {
        return super.then(v => f(v[0]), r);
    },
    // XXX Note that I wouldn't have to override this if it weren't for the
    // check in step 8 of CreatePromiseCapabilityRecord.
    resolve(v) {
        return new MonadicPromise(function(r) { r(v); });
    }
};
MonadicPromise.prototype.monadic = true; // just for demonstration purposes

// Let's test it out!

MonadicPromise.resolve(5).then(function(x) {
    console.log('x is', x); // 5, of course.
});

var resolve;
new MonadicPromise(function(r) { resolve = r; }).then(function(x) {
    if (x.monadic) {
        console.log('this is another promise!');
        return MonadicPromise.resolve(x); // wrap it again
    }
}).then(function(x) {
    console.log('got', x);
    if (x.monadic) {
        console.log('still monadic');
        return x;
    }
}).then(function(x) {
    console.log('finally resolved', x);
});
resolve(MonadicPromise.resolve(5));
--- end monadic.js ---

I hope this demonstrates that with the current spec you can, in fact,
have your Monadic Promise cake, if that's your preference.

I would suggest that the check in step 8 of
CreatePromiseCapabilityRecord be rewritten to reassign the result of
the constructor to capability.promise; that will make subclasses like
this one a bit more straightforward to implement (without having to
closely read the spec to figure out why TypeErrors are being thrown).
  --scott
forbes at lindesay.co.uk (2014-02-14T00:11:18.844Z)
For your consideration, here is an implementation of Monadic Promises,
as a Promise subclass:

(This version is inexpertly hand-rewritten into ES6; see
https://gist.github.com/cscott/b1966d485807d9a8cc39 for an ES5 version
which has been tested to work against
https://github.com/paulmillr/es6-shim/pull/215)

```js
class MonadicPromise extends Promise {
    constructor(exec) {
        // the promise constructor needs to be new each time,
        // in order to thwart the optimization in Promise.resolve
        // (formerly Promise.cast)
        class MP extends MonadicPromise {
            constructor(exec) {
                Promise.call(this, (f,r) => exec( v => f([v]), r));
            }
        }
        return new MP(exec);
    },
    then(f, r) {
        return super.then(v => f(v[0]), r);
    },
    // XXX Note that I wouldn't have to override this if it weren't for the
    // check in step 8 of CreatePromiseCapabilityRecord.
    resolve(v) {
        return new MonadicPromise(function(r) { r(v); });
    }
};
MonadicPromise.prototype.monadic = true; // just for demonstration purposes

// Let's test it out!

MonadicPromise.resolve(5).then(function(x) {
    console.log('x is', x); // 5, of course.
});

var resolve;
new MonadicPromise(function(r) { resolve = r; }).then(function(x) {
    if (x.monadic) {
        console.log('this is another promise!');
        return MonadicPromise.resolve(x); // wrap it again
    }
}).then(function(x) {
    console.log('got', x);
    if (x.monadic) {
        console.log('still monadic');
        return x;
    }
}).then(function(x) {
    console.log('finally resolved', x);
});
resolve(MonadicPromise.resolve(5));
```

I hope this demonstrates that with the current spec you can, in fact,
have your Monadic Promise cake, if that's your preference.

I would suggest that the check in step 8 of
CreatePromiseCapabilityRecord be rewritten to reassign the result of
the constructor to `capability.promise`; that will make subclasses like
this one a bit more straightforward to implement (without having to
closely read the spec to figure out why TypeErrors are being thrown).