GHC since version 9.8 allows us to create callbacks from JS to Haskell code, which enables us to create full-fledged browser apps. This article shows

Case Study — Using a JavaScript component inside a Haskell application | The Haskell Programming Language's blog

submited by
Style Pass
2025-01-09 09:30:04

GHC since version 9.8 allows us to create callbacks from JS to Haskell code, which enables us to create full-fledged browser apps. This article shows how to use the JS backend with foreign component libraries.

Any useful browser single-page application needs to be able to react to user input to modify the webpage content on response. Since GHC version 9.8 release, we can instantiate JavaScript-level functions with Haskell closures, allowing us to pass Haskell-level actions to DOM event listeners.

In the above snippet we're creating an IORef and pass a callback incrementing it to a foreign function that installs a button in body, counting a number of clicks (note for brevity I used a multiline syntax that is not yet available for foreign calls). The callback closes over the IORef and correctly updates the number after each click.

Callbacks fully enable probably the most fascinating purpose of JavaScript backend, which is web programming. GHCJS has been around for quite some time now, however it is both outdated (being a GHC fork requiring separate maintenance; currently stuck on 8.10) and cumbersome to use (often necessitating a separate setup, typically through Nix). In one of my previous companies, while evaluating potential options for rewriting the frontend, I decided to use PureScript. It was close enough to Haskell and very easy to set up - it can be installed directly through npm, has its own stack-like package manager spago with a suite of existing bundler plugins, and a blazing fast language server. During this journey I was using purescript-halogen library - a typesafe, declarative VDOM framework based on The Elm Architecture.

Leave a Comment