2013-08-30

The first thing we need on our journey is a compiler that translates out haskell to javascript. On this page: The JavaScript Problem you can find a list of compilers that are able to do that. I will focus on UHC and haste. GHCJS also seems promising, and I might try it later.

So we want to write a little hello world program. The equivalent in javascript would be

which replaces the contents of the document with "Hello, World!". Let us get started.

UHC

The Utrecht Haskell Compiler has a backend allowing to compile haskell to javascript. This page links all the information about the JavaScript backend: UHC-JS

Installing UHC

First we have to install UHC. You can find the code for UHC here UHC GitHub. The build instructions can be found in the EHC sub directory.

But first some dependencies are needed. On ubuntu linux I install them with apt-get:

We also need to install a few haskell packages via cabal:

To install UHC, first clone the repository and change into the EHC directory. Then build and install UHC.

In blogs it is common to suggesting getting a cup of coffee at a moment like this, because the make command may take a while. So get a cup of coffee!

If everthing worked out, UHC should be installed and you can compile to javascript via

(Or however your haskell file is called).

Hello World with UHC

We need to do two things:

Get the document.

Call write on the document with "Hello, World!" as parameter.

The FFI (ForeignFunctionInterface) of the js backend of UHC is described here Improving UHC js For our purposes, it works like this:

Where "jscommand" is the command in javascript, "haskellName" the name of the haskell function we want to define and "Type" the type of the haskell function. "jscommand" may contain "%N" where N is a number refering to the N-th parameter of the haskell function.

So to get the document we first define a type for it and then import a corresponding javascript command

To get the document we just have to call "document" in javascript. This returns us the document in the IO monad. The document is in the IO monad because we a calling a foreign function which might have side effects.

Now we want to call "write" on a document.

Because the "%1" is in front of the ".write", the first argument to haskell function "write" (which is the document) is the object write is called on (this can all be found in Improving UHC js.

Note that the second argument is of type JSString and not of String. This is because a string in haskell is not the same as a string in javascript. We have to convert a haskell string to a javascript string

Now we are ready to write our hello world:

Haste

Installing haste

Haste can be found here: Haste GitHub. Instructions for installation can also be found on that page (just read the Building section). It requires installation of fursuit, which can be found here: Fursuit GitHub.

Hello World with haste

Again, we need a way to import a function to get the document and to write into the contents of the document. Information on how to import javascript functions can be found in the doc subdirectory of the haste repository.

Update: The way FFI functions have to writting with haste has changed since the blog post has original been written. At that time returning values from javascript to haskell was a little bit more cumbersome. I have updated this blog post to reflect the new way of doing it. I hope I did not forget something in the process. So if you find an error, please comment.

Haste is not as flexible as UHC when importing JavaScript functions. It does not allow placing the parameters of the haskell function in the javascript code with "%N". It also does not allow the custom type "Document" to be used as a parameter or return type. Instead "JSAny" must be used.

So we create a file "helpers.hs" with out Javascript helper functions:

This now allows us to write hello world in Haste:

Compile this with:

Now all we need to do is embed this file in a html page:

Open this with a browser of your choice (I only tried chromium) and it should work.

Edit: Trying it out

As suggested in a comment, I have uploaded the compiled javascript file (the haste version because the UHC version has several dependencies) here: Hello, World!

Download it and this html file into the same directory. Than open the html with a browser of your choice (tested on ubuntu linux, chromium).

Edit: Rewrote with pandoc


Writing JavaScript games in Haskell by Nathan Hüsken is licensed under a Creative Commons Attribution 3.0 Germany License.

Show more