As crazy as it seems, using React and Haskell together just may be a good idea.
I was driven to create this thing because I had a large existing Haskell codebase I wanted to put online. However, even without existing code, I think a lot of problems are better modeled in Haskell than JavaScript or other languages. Or you might want to use some existing Haskell libraries.
Let's put a simple paragraph on the page:
sample :: ReactNode a sample = p_ [ class_ "style" ] $ em_ "Andy Warhol" main :: IO () main = do Just doc <- currentDocument let elemId :: JSString elemId = "inject" Just elem <- documentGetElementById doc elemId render sample elemThat creates a DOM node on the page that looks like:
<p class="style"> <em>Andy Warhol</em> </p>We can make that a little more complicated with some more child nodes.
sample :: ReactNode a sample = div_ [ class_ "beautify" ] $ do "The Velvet Underground" input_ "Lou Reed"But of course that input doesn't do anything. Let's change that.
sample :: JSString -> ReactNode JSString sample = div_ $ do "Favorite artist:" input_ [ onChange (Just . value . target) ] text strThe first step is a working GHCJS installation. The easiest way is to download a virtual machine with GHCJS pre-installed. I recommend ghcjs-box.
Now that GHCJS is installed we can use cabal to create a project.
$ mkdir project $ cd project $ cabal init # generate a .cabal fileNow edit the cabal file to include dependencies.
build-depends: base >= 4.8 && < 5, ghcjs-base, ghcjs-dom, react-haskell >= 1.3Now we can write Main.hs.
sample :: ReactNode a sample = p_ [ class_ "style" ] $ em_ "Andy Warhol" main :: IO () main = do Just elem <- elemById "id" render sample elemReact-Haskell is a great tool for building web UI from Haskell. However, you may want to consider the alternatives:
- By writing plain React / JSX you can speed development by avoiding the GHCJS compilation step. This also has the advantage of being a bit more universal - more people use React through JSX than React-Haskell.
- ghcjs-react is a very similar project.
- Reflex is an FRP system built with GHCJS in mind.
