[Haskell-cafe] IO-oriented cache library for interacting with GUI

Alexey Karakulov ankarakulov at gmail.com
Thu Sep 16 12:33:54 EDT 2010


Hi. I'm writing GUI (gtk) program which purpose is take some data as user
input, perform some evaluations, and produce some plots and coefficients.
Since some evaluations take significant time (about 10 seconds), I try to
cache results. The problem is that dependency structure is quite
complicated, something like this:

   a* -> x, b*
   x -> c
   x, b* -> d

where
  α -> β means that β depends on α
  values designated by *a*,*b*,*c*,*d* can be showed to user by request, and
*x* is internal value
  values designated by letters with asterisk (*a**,*b**) can be edited by
user

Consider *x*. I have two values:
    xCache :: IORef X
    xUpToDate :: IORef Bool

Initial state is:
    xCache <- newIORef undefined
    xUpToDate <- newIORef False

Since *x* is evaluated once, I do
    xCache `writeIORef` x
    xUpToDate `writeIORef` True

When user changes the value of *a *and saves it, all dependent on *a *values
cache is expired:
    xUpToDate `writeIORef` False
    (recursively do it with all cache depends on *x*)

When it comes to handling all *a,b,c,d,x *dependencies the code becomes a
mess. I now have something like

    import Data.Functor
    import Data.IORef
    import Control.Monad

    data Mutable a = Mutable { ref :: IORef a, onChange :: IO () }

    change :: Mutable a -> a -> IO ()
    change Mutable {..} a = ref `writeIORef` a >> onChange

    data Cache a b = Cache { fn :: a -> b, arg :: IORef a, cached :: IORef
b, upToDate :: IORef Bool }

    expire :: Cache a b -> IO ()
    expire Cache {..} = upToDate `writeIORef` False

    update :: Cache a b -> IO ()
    update Cache {..} = do
       utd <- readIORef upToDate
       unless utd $ writeIORef cached =<< fn <$> readIORef arg

    test = do
      aRef <- newIORef undefined
      xRef <- newIORef undefined
      xCache <- Cache (^2) aRef xRef <$> newIORef False
      let aMut = Mutable aRef (expire xCache)
      aMut `change` 1
      update xCache
      print =<< readIORef xRef -- 1
      aMut `change` 2
      print =<< readIORef xRef -- still 1
      update xCache
      print =<< readIORef xRef -- now 4

I'd like to know if there is some library that could help me.

(Sorry for my English)
--
All the best,
Alexey
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100916/15b0e0a7/attachment.html


More information about the Haskell-Cafe mailing list