function keyword anonymous functions are also supported.
value, under the guise of the type
JSVal. Values having this type
are mostly opaque to Haskell codes: you can think of JSVal as a data type whose
data constructors aren’t exposed. Its main use case is to pass opaque
Nevertheless the module
base contains functions for
working with foreign
JSVal objects. Currently, it provides the following
It also contains functions for working with objects:
getProp :: JSVal -> String -> JSVal- object field access
Some types are able to be used directly in the type signatures of foreign
exports, without conversion to a
JSVal. We saw in the first example
Int is one of these.
that match the Haskell type. This means types such as the Haskell
type aren’t supported directly, because they’re lists - which don’t have
The following types are supported in this way:
base defines the type
as well as several functions to construct callbacks from Haskell functions
of up to three
JSVal arguments. Unlike a regular function, a
This example will call our
Example! as an argument. On the last line,
the callback memory is freed. Since there’s no way for the Haskell JS runtime
must be manually released when no longer needed.
On the first line of
main, we see where the
Callback is actually
syncCallback has versions up to three,
including a zero-argument version with no suffix. To use callbacks with more
objects or arrays as required.
There are three categories of functions that create callbacks, with the arity-1 type signatures shown here for demonstration:
syncCallback1 :: (JSVal -> IO ()) -> OnBlocked -> IO (Callback (JSVal -> IO ())): Synchronous callbacks that don’t return a value. These take an additional
data OnBlocked = ThrowWouldBlock | ContinueAsyncargument for use in the case that the thread becomes blocked on e.g. an
syncCallback' :: (JSVal -> IO JSVal) -> IO (Callback (JSVal -> IO ())): Synchronous callbacks that return a value. Because of the return value, there is no possibility of continuing asynchronously, so no
OnBlockedargument is taken.
asyncCallback :: (JSVal -> IO ()) -> IO (Callback (JSVal -> IO ())): Asynchronous callbacks that immediately start in a new thread. Cannot return a value.
There is no checking that the passed arguments match the callback, so the
following example compiles and correctly prints 10, despite the argument being
passed as an
Int to a
Callback that accepts a
14.4. Callbacks as Foreign Exports¶
<button onClick="globalF('Button pressed!")>Example</button>
We have to make sure not to use
releaseCallback on any functions that
are to be available in HTML, because we want these functions to be in