GHC JS backend - calling Haskell callback in a foreign function

I have a problem how to pass Haskell callbacks into JS foreign functions. I followed an example here:

and created the following gist:

The intention is to add another bullet point to the list whenever the user clicks on body (but a true intention is to see how callback passing works). All compiles, however, when I click on body, I get a following error:

Uncaught TypeError: fun is not a function
    at document.body.onclick (all.js:57263:48)
document.body.onclick @ all.js:57263

When I print fun via a console.log, it seems that indeed it’s not a function, but rather some complicated object representation. How do I make it executed on user click?


foreign import ccall "wrapper" createFunPtr :: (IO ()) -> IO (FunPtr (IO ()))

ccall: should that also be javascript, like the other foreign imports?

No, it causes GHC panic:

<no location info>: error:
    panic! (the 'impossible' happened)
  GHC version 9.7.20230112:
  InScope {$wccall_d1YL $wccall_d1YS $wccall_d1YZ logConsole
           setBodyOnClick setInnerHtml $trModule}

I think wrapper always needs to be ccall, but don’t have that much experience in FFI.

Actually we discussed this in the PR for the blog post: