Hacker News new | ask | show | jobs
by bazoom42 646 days ago
Maybe I’m confused, but I dont see how Promise.then() corresponds to bind? If I understand correctly, the point of the bind function is you pass a callback which itself return the monad type. But the Promise.then() callback should not return a monad but just the regular result value of invoking the callback.

So in essence Promise.then() is like Array.map() while bind is like Array.flatMap()

Edit: It seems you are correct, you can indeed return a promise in the callback and it compose correctly. But in your example the callback does not return a promise and is therefore not an example of monadic bind.

1 comments

I had a caveat in my original post re. the implicit wrapping of the `Promise.then()` callback's (pure) return value in a new Promise, and how this differs from Haskell's monadic bind; I had hoped to make a loose analogy while pointing out the differences for the sake of illustration. However it is indeed also possible to return a Promise from `.then()`'s callback, which is closer to Haskell's bind: [0]

    The behavior of the returned promise (call it p) depends on the handler's
    execution result, following a specific set of rules. If the handler function:

    * returns a value: p gets fulfilled with the returned value as its value.

    [...]

    * returns an already fulfilled promise: p gets fulfilled with that promise's value as its value.
... then you can obtain a solution closer to the Haskell translation by using the behaviour of the second cited bullet point from the MDN article:

    const promise1 = Promise.resolve(123);

    promise1.then(v => Promise.resolve(v * 2)).then((value) => {
      console.log(value);
      // Expected output: 246
    });
[0] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
This article argues that while promises support the required operations for monad, they do not support the monad laws:

https://www.siawyoung.com/promises-are-almost-monads/

It's a good point. `Promise::resolve()` "flattens nested layers of promise-like objects (e.g. a promise that fulfills to a promise that fulfills to something) into a single layer." [0]

The example was meant to be more of an illustrative analogy than an exact correspondence.

[0] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...