4

I am using wxHaskell to create a simple GUI that has typical components like Buttons, Panels, etc.

When some of these components perform an action (like callback), the generic status of the application can change.

To keep the status I am using IORef as a sort of pointer to a generic data structure with all the properties of the status self.

Anyway using IORef as a sort of top level mutable state is generally not considered a good solution based on https://wiki.haskell.org/Top_level_mutable_state. It might be better State/StateT monad.

wxHaskell is a "bind" to an object oriented library (wxWidgets) and using a State monad is hard unless it's "hooked" to the main event loop thread.

What is the best way to manage a generic GUI status with Haskell in a functional programming way?

1 Answer 1

2

TL;DR: FRP

The thing that makes this not as trivial as it is in an imperative impure setting is that the state isn't only being modified on our side, the system modifies it too, and in realtime (e.g. when the user moves the window, or even merely moves the cursor). And we can't listen to events and update our values, because they are immutable.

If we were the only ones responsible for the state that just would have been a whole lot easier.

This is what makes people resort to IORefs: they don't know what to do, and this pattern is the only solution they're familiar with -- it's great in imperative languages, after all. It's kind of easy, and it's really fast, isn't it? (unlike polling for example).

Well, we obviously can't be pure here, GUI is all about side-effects, but we do want to try to remain as pure as much as we can, and we'd even really like to do so with the functional constructs we've grown to love so much (foldables, functors, applicatives, sometimes arrows), and this is pretty much what FRP (Functional Reactive Programming) can do for you.

There are many FRP libraries out there, imo an easy one is reactive-banana.

I can't think of anything more idiomatic, however if that's an overkill, top-level mutable state shouldn't really be the answer. I'd keep the state, either directly in main, or group it in datatypes (with IORef fields) if there are too many and it becomes an IO zoo.

Tip: I haven't tried it, but I think FRP with a lens library can make state management incredibly easy.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.