Coding Struggles
About Me PureScript Dates PureScript Cookbook
    Recipes:
  • Writing Hello World
  • Printing debug messages
  • Working with newtypes
  • Wrapping JavaScript functions
  • Basic handling of JSONs

Wrapping JavaScript functions

1 minute read

We’ll se how to wrap three types of functions:

  • pure functions
  • effectful sync functions
  • async functions

Pure functions

JavaScript functions are usually uncurried, i.e.:

function foo (a, b, c) {
  return a + b + c;
}

Since in PureScript all functions are curried, we can save us a lot of boilerplate by using Data.Function.Uncurried from purescript-functions.

Continuing from the example above, let’s say we have this in our Main.js:

exports.fooImpl = function (a, b, c) {
  return a + b + c;
}

Then in our Main.purs we can write:

import Data.Function.Uncurried (Fn3, runFn3)

foreign import fooImpl :: Fn3 Int Int Int Int

foo :: Int -> Int -> Int -> Int
foo = runFn3 fooImpl

They go up to 10 arguments and it’s very unlikely that more would be needed!

Effectful sync functions

There’s a similar set of functions to work with effectful functions, and they’re are under Effect.Uncurried.

Let’s say we have:

exports.effectfulFooImpl = function (target, amount) {
  launchMissiles(target, amount);
}

Then we can wrap it like this:


foreign import effectfulFooImpl
  :: forall eff
   . EffectFn2 String Int Unit

effectfulFoo
  :: forall eff
   . String
  -> Int
  -> Effect Unit
effectfulFoo t a = runEffectFn2 effectfulFooImpl t a

Async functions

To work with async functions, I’ve found that the easiest way is to use Effect.Aff.Compat from purescript-aff.

// let's suppose get makes an ajax request.
exports.ajaxGetImpl = function (request) {
  return function (onError, onSuccess) {
    get(request, function (err, response) {
      if (err) {
        onError(err);
      } else {
        onSuccess(response);
      }
    });
  }
}

And then wrap it like this:

foreign import ajaxGetImpl
  :: forall eff
   . Request
  -> EffectFnAff Response

ajaxGet
  :: forall eff
   . Request
  -> Aff Response
ajaxGet = fromEffectFnAff <<< ajaxGetImpl

It would be better to return a canceler, but you can find an example on purescript-aff’s documentation page.

Share this post!
Theme crafted with <3 by John Otander (@4lpine).
</> available on Github.