[Haskell-cafe] CBRef, a wrapper around IORef with callbacks

Dmitry V'yal akamaus at gmail.com
Tue Dec 14 20:43:04 CET 2010


Hello,
	while building GUIs using Gtk2HS I always struggled with the following 
question: how to sync the state of the GUI with the state of the rest 
application. I usually make several IORefs store the state there. But 
it's quite easy to forget to update relevant parts of GUI when state 
changes, especially then it's done in several places, say, by user's 
request and by some internal event.

	Some time ago I realized a pattern which proved to be useful for me 
several times. I wrapped IORef in a type:

data CBRef a = CBRef {v_ref :: IORef a, callbacks :: IORef [a -> IO()] }

now I add callbacks using

addCB :: CBRef a -> (a -> IO()) -> IO ()
addCB r cb = modifyIORef (callbacks r) (++[cb])

which fires then the value is changed:

writeCBRef :: CBRef a -> a -> IO ()
writeCBRef r v = do
   writeIORef (v_ref r) v
   cbs <- readIORef (callbacks r)
   mapM_ ($ v) cbs

all the remaining IORef-like interface is present too.

By using these callbacks for updating GUI I can be sure all it's parts 
are in sync.

I suspect it's a special case of more general idea. Can anyone give a hint?

Also, do you think it's useful enough to be uploaded to Hackage? Or 
maybe something similar is already there?

How do you organize your GUI applications?

Best wishes,
Dmitry



More information about the Haskell-Cafe mailing list