packages feed

hstzaar-0.7: src/Var.hs

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