Interacting with JS in PureScript
This part resolves around using PureScript functions in JavaScript, and the other way around - using JavaScript functions in PureScript.
Importing foregin JS functions in PureScript
For this task, there is the so-called foreign function interface. For making a single or multiple JS functions available in PureScript, we always need a JavaScript file, holding the functions, and a PureScript file, referencing those, making them available as PureScript imports.
Let's create a JS function for doubling a given integer. To do so, create in the src-folder of your PS app a Calculations.js:
'use strict'
exports.double = function (n) {
return 2 * n
}
Then, the Calculations.purs, to make this function available:
module Calculations where
foreign import double :: Int -> Int
Finally, you can import and use the double function:
import Calculations
double 2
-- 4
For making existing functions of JavaScript available, you can just mark them to be exported. Again, our Calucations.js:
'use strict'
exports.power = Math.power
Importing stays the same.
Importing PureScript functions in JavaScript
The most interesting part might be to import functions in JavaScript. In this example, we will import a PS function in Node.js.
In the Main.purs file, I stored a function "double":
double :: Int -> Int
double n = n * 2
Now, when running
spago bundle-app
Our PS file will be transcompiled to JavaScript, and stored in /output/Main/index.js, from where we can import functions.
NOTE: No, this is not the same as running spago bundle-app and then to import the root-level index.js, which is generated. For bundling the index.js in the root of your PS project directory, dead code is removed - this includes functions, never called from your PS main function. Therefore, using the central index.js is for building a whole PS project. The way I just taught you is for importing single functions, written in PureScript.
Importing uncurried functions from JavaScript
The example we had before covered a function in JavaScript (double) that has only one parameter. As you might know, all functions in PureScript only have a single-parameter, for multiple ones, we use currying, covered here.
Therefore, we can't import a JS function with more than one parameter as before - we need to prepare PureScript for it.
Let's rewrite our Calculation package this way:
exports.addNums = function (a, b) {
return a + b
}
Now, before writing the PS code, make sure to import the package for the wrapper we need:
spago install purescript-functions
Calculations.purs:
module Calculations where
import Data.Function.Uncurried
foreign import addNums :: Fn2 Int Int Int
Fn2 is the function that enables us to use an uncurried function with two parameters.
Now, we can use addNums in the REPL or code like this:
import Calculations
import Data.Function.Uncurried (runFn2)
runFn2 addNums 2 2
-- 4
Reminder: When having X parameters in an uncurried JS function, make sure to use runFn and FnX. For example, runFn3, runFn4 up to runFn10 are all available in the package.