-- 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