packages feed

hstzaar-0.6: src/StateVar.hs

-- State variables for IO refs
-- Encapsulates mutable references with callback functions 
-- pbv, 2011
module StateVar
    ( StateVar,
      new, get, set, modify, watch
    )  where

import Data.IORef

-- a state variable is pair of mutable ref and mutable callback
data StateVar a = StateVar !(IORef a) !(IORef (a -> IO ()))

-- make a new state var with given value and null callback
new :: a -> IO (StateVar a)
new v = do ref <- newIORef v
           callback <- newIORef (\_ -> return ())
           return (StateVar ref callback)

-- assign to a state var
set :: StateVar a -> a -> IO ()
set (StateVar ref callback) v
    = do writeIORef ref v
         cb <- readIORef callback 
         cb v

-- fetch the value of a state var
get :: StateVar a -> IO a
get (StateVar ref _) = readIORef ref

-- update a state var using a pure function
modify :: StateVar a -> (a -> a) -> IO ()
modify (StateVar ref callback) f
    = do modifyIORef ref f
         v <- readIORef ref
         cb <- readIORef callback
         cb v

-- modify the callback for a state var
-- finishes executing the callback with current value
watch :: StateVar a -> (a -> IO ()) -> IO ()
watch (StateVar ref callback) cb 
  = do writeIORef callback cb
       v <- readIORef ref
       cb v