Exposing PureScript as a Seamless JavaScript Library

Lately I’ve been experimenting with integrating PureScript into some of my JavaScript projects. It’s only recently that I discovered two key tools in doing it well: EffFn which I discovered watching Porting Try PureScript to PureScript, and the Promise type from purescript-aff-promise.

Taking drag-and-drop-m3u-maker as an example, I was previously calling a PureScript function from JavaScript like this…

// PureScript signature
// foldToM3U :: forall e. Array AudioDetails -> Aff e String

// JavaScript call
PS.DragAndDropToM3U.foldToM3U(files)(function(m3u) {
  // Do something with m3u
}, function(err) {
  // Something went wrong
})();

Not very pretty. But now that I know about EffFn and purescript-aff-promise, I can expose this as a seamless function to be used in JavaScript…

foldToM3U_ :: forall e
  . EffFn1 e (Array AudioDetails) (Promise String)
foldToM3U_ = mkEffFn1 \details ->
  Promise.fromAff $ foldToM3U details
PS.DragAndDropToM3U.foldToM3U_(details)
  .then(function(m3u) {
    // Do something with m3u
  }, function(err) {
    // Something went wrong
  });

Much much nicer! Basically, EffFn will let you run effectful uncurried functions. Read the documentation of Control.Monad.Eff.Uncurried for more information.

As a side note, I could have exported the function as foldToM3U, but I kind of like the idea of having a naming convention for PureScript functions that can be run in JavaScript. Appending the underscore is a way to indicate that.