No description, website, or topics provided.
Clone or download
Latest commit 72a6fb2 May 28, 2018
Type Name Latest commit message Commit time
Failed to load latest commit information.
src/Control changes for 0.12 May 26, 2018
test changes for 0.12 May 26, 2018
.gitignore Initial commit Jan 21, 2016
.travis.yml changes for 0.12 May 26, 2018
LICENSE Create LICENSE Sep 12, 2016 Update May 27, 2018
bower.json changes for 0.12 May 26, 2018
package-lock.json upgrade to Aff 4.0 Oct 7, 2017
package.json changes for 0.12 May 26, 2018


Simple library for interop between Aff and JavaScript promises.

No typeclass instances etc are provided to use Promises directly - the intention is that your PureScript code uses Aff internally, and is only wrapped as a Promise to present an API for consumption in JavaScript code (and vice versa).

Exposing promises: Aff to Promise

The origin of this library was to solve the following problem: I want to write asynchronous code in Aff, but I need to expose this as an API to JavaScript in the form of a Promise.

Therefore the majority of code can be written to return an Aff, in this example using readTextFile from purescript-node-fs-aff:

getLinesAff :: Aff (Array String)
getLinesAff = do
  text <- readTextFile Encoding.UTF8 "data.txt"
  pure $ split (Pattern "\n") text

and this can be exposed as a function returning a promise:

import Control.Promise as Promise

getLines :: Effect (Promise (Array String))
getLines = Promise.fromAff getLinesAff

This function returns an Effect beause a promise is "already running". A JavaScript function consuming this API would just call getLines().then(...).

Consuming promises: Promise to Aff

The reverse problem occurs when wrapping a JS library that uses promises for asynchronous behaviour (Aff comes with a perfectly good function to deal with consuming libraries that use callbacks).

Consider the case of consuming the fetch API.

exports.fetchImpl = function (url) {
  return function() {
    return fetch(url);
foreign import data Response :: Type
foreign import fetchImpl :: String -> Effect (Promise Response)

Notice that the fetch(url) call is wrapped in a thunk and imported as an Effect, because otherwise the fetch operation would be initiated as a side-effect of a pure function - while fetch returns a promise, at the point the function returns the network request has already been initated.

The response can then be converted to an Aff and consumed easily:

import Control.Promise as Promise

fetch :: String -> Aff String
fetch url = liftEffect (fetchImpl url) >>= Promise.toAff


API documentation is available on Pursuit.