Creating a GUI application in Haskell

Despite its strengths in GUI application development, Haskell is often overlooked for this, and other “front-end” tasks, instead being relied on more commonly for back-end development.

What are your thoughts on this?

*This article was originally written in 2015 and updated in March 2024 to reflect the process of creating a GUI application from scratch with Haskell and GTK+.

4 Likes

This is the first time I’ve heard “GUI application development” as a strength of Haskell. So, unfortunately, I would somewhat doubt that statement.

Generally, I think the issue is not that Haskell is unsuited for such a task, but simply that it takes a large amount of effort to develop and maintain a good/extensive UI library.

From a more theoretical viewpoint: actually I don’t think we have a very good “fine grained reactivity” type of framework for UI development. Currently, I find the MVC type approach (e.g. Elm architecture like) easiest to use, but having to generate some entire view-tree and diffing it against the current state is inherently wasteful. So I find that inherently a bit off-putting (even though it seems to work reasonably well in practice). The FRP-like approaches seem better in that regard, but developing a high performance GUI that way seems somewhat hard as well. Furthermore, I don’t really like that (e.g. in reflex) everything becomes monadic.

1 Like

This is from 2016 and a lot has changed. Almost none of the libraries mentioned are still good options.

Currently, I think the best native GUI libraries are monomer and haskell-gi (which uses GTK). If you don’t mind using a browser then threepenny-gui and reflex are also good options.

6 Likes

Thanks for the insights! We would definitely give it a try. Although the piece was originally written in 2016, we recently made some updates based on what is currently available.

2 Likes

Ah, sorry I only skimmed the post and got hung up on the alternatives section. I don’t think any of those is really maintained any more.

Anyway, it’s great that you’re updating old posts on topics like these that can change rapidly!

3 Likes

Strengths, since when is haskell good for gui? Javascript is superior no? A

I was about to post something like this when Discourse notified me that @jaror had already posted it. Note that even the README of gtk3 recommends using haskell-gi instead.

For more on current GUI libraries, I wrote a comprehensive article on the current state of the art. It’s two years old now, but I believe it should still be accurate.

1 Like

I’ve done GUI development in Haskell with Gtk. No matter what bindings you use, it doesn’t feel idiomatic at all.

I never went into all this FRP stuff and I don’t think there’s a comprehensive FRP abstraction on top of Gtk that’s more than just a PoC.

2 Likes

To be fair, GTK feels unidiomatic even in C. It’s probably the worst-designed GUI library I’ve seen. If anything, I’d say that haskell-gi does about as good a job at taming the mess as is possible in Haskell.

Indeed, I don’t believe there is.

2 Likes

I haven’t seen @owi Oscar Wickstrom’s declarative GTK package mentioned yet so here it is.

I haven’t used it but I think this package has the right idea. We’re more than ten years into the model-view-update GUI revolution and from my experience model-view-update is the most sane way to write GUIs.

1 Like

The big problem with the Elm architecture is that it forces you to store all of your state in one big global record. And global mutable state is very rarely a good idea.

The interesting thing about gi-gtk-declarative is that it isn’t really a GUI library itself — it just provides a toolkit on top of gi-gtk to enable ‘virtual DOM diffing’ approaches. So, you can use it to build the Elm architecture (which is what gi-gtk-declarative-app-simple does). But then you can use it to build other architectures too: for instance, Komposition uses indexed monads.

But, as yet, I haven’t seen an approach which beat just using gi-gtk directly. And in any case, I’m pretty sure gi-gtk-declarative is unmaintained.

1 Like

For example, this image from the Elm-MVU page:

image

…has a curious resemblance to:

image

(…from page 4 of 60 in Tackling the Awkward Squad.)

Therefore:

  -- the type of the entire program
type Dialogue = [Request] -> [Response]

type Request  = Html
type Response = Msg

Notice that the state is implicit, it being an inherent part of the running program within its Dialogue of definition - making that state conveniently available for easier access and modification (i.e. making it explicit ) in Haskell usually means a change of program type is needed; something resembling:

type MonadState s m => DialogueM s m = [Request] -> m s [Response] 

(or perhaps an arrow type). It’s yet another reason why global mutable state is very rarely a good long-term option…