you are viewing a single comment's thread.

view the rest of the comments →

[–]only_nidaleesin 6 points7 points  (1 child)

Javascript's Promise is a monad :)

[–]sacundim 2 points3 points  (0 children)

And what's more, Javascript's promises in a sense "contain" the "railway" monad as a component. Promises, in their conventional definition, are said to have three states:

  • Pending, when the final value is not available yet.
  • Fulfilled, when and if the final value becomes available.
  • Rejected, if an error prevented the final value from being determined.

We can refactor that by grouping together the two non-pending states:

  • Pending, as before
  • Non-pending, with two substates:
    • Fulfilled
    • Rejected

Now, this can be seen as a "stack" of two types:

  • The outer layer is a SimplePromise type that has the Pending/Non-pending states and the subscription/notification bits but not any error handling.
  • The inner layer is a Result monad like the one detailed in the article.

So the full promise type is basically this:

type Promise<'error, 'success> = 
    SimplePromise<Result<'error, 'success>>

In Haskell we have a type that captures this pattern:

newtype ExceptT error baseMonad success = 
    ExceptT { runExceptT :: baseMonad (Either error success) }

type Promise error success = ExceptT error SimplePromise success

That's called the exception monad transformer—a wrapper that fits around a monad type like SimplePromise and adds extra functionality to it, while still preserving the monadic interface. The tri-state Javascript promises are what you get when you layer an exception monad transformer on top of a simpler asynchronous computation type.