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