-- State variables for IO refs -- Encapsulates mutable references with callback functions -- pbv, 2011 module Var ( Var, new, get, set, modify, watch ) where import Data.IORef -- a state variable is pair of mutable ref and mutable callback data Var a = Var !(IORef a) !(IORef (a -> IO ())) -- make a new state var with given value and null callback new :: a -> IO (Var a) new v = do ref <- newIORef v callback <- newIORef (\_ -> return ()) return (Var ref callback) -- assign to a state var set :: Var a -> a -> IO () set (Var ref callback) v = do writeIORef ref v cb <- readIORef callback cb v -- fetch the value of a state var get :: Var a -> IO a get (Var ref _) = readIORef ref -- update a state var using a pure function modify :: Var a -> (a -> a) -> IO () modify (Var 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 :: Var a -> (a -> IO ()) -> IO () watch (Var ref callback) cb = do writeIORef callback cb v <- readIORef ref cb v