This post is about getting the assurance of Haskell with the GUI love of Cocoa. Though it is definitely Cocoa-specific in places, using the FFI there’s no reason why it couldn’t be abstracted out to support any GUI environment with a little work.
This is based on work by Tim Scheffler which you can see at his github page. There’s also an associated blog post with far more detail about the implementation.
I tested this with Mac OS X 10.7, XCode 4.1, and GHC 7.0.4. If run into problems, there are two places to look for tweakables. The first is the Build Settings pane in XCode. Specifically, the project only lists x86_64 in “Valid Architectures”, and is targetted to 10.6 because the project I was using it for originally required support for it. The second is under Build Phases, the last phase is a Run Script phase that runs a Python script to assemble the final binary, among other things.
Check out a copy of cocoa-app-shell
Give it a spanky new name. If you are using XCode 4 this is relatively easy if you slow-click on the top level of the project heirarchy.
If you did that right, you’ll see something like this, assuming you decided to name the project “Does It Work”
There are two ways to connect methods to Haskell code. The first is connecting events to objects - buttons, text areas, and the like.
The second is calling functions directly. This is a bit more involved.
cocoa-app-shell is about as simple as you can get.
If you enter some text in the textarea by From Event, it will convert it to upper case by simply calling toUpper
. This is bound programatically by haskell using the following code.
(For context, start at Controller.hs - line 78)
Pretty simple. As long as the outlet named “fh_hello_field” is mapped from Interface Builder to the main class it just works.
Poking around in the code, you’ll also come across this line:
Which, as you might expect, connects a button’s press event to a Haskell function. Again, not terribly complicated.
The second field in the example takes the string out of the textfield and converts it to uppercase, this time by calling a function straight up. The objc side of this is in a handler for the button press.
And now, here’s the Haskell side of things.
I have delivered one application using this and have plans for a couple more. I’m hoping to update the cocoa-app-shell project with a new version that has Sparkle already configured. We used it in the first deliverable and it really enjoyed it.
I need to take a bare machine and list all of the steps to get it building correctly.
Sparkle integration out of the box would be really nice. I have all of the scripts and things from my earlier application so this should be relatively painless.