module Control.Reagent
where
import Data.IORef
import Data.Atomics
type Reagent a = forall b. (a -> IO b) -> IO b -> IO b
react :: Reagent a -> IO a
react r = try where
try = r finish try
finish x = return x
atomicUpdate :: IORef a -> (a -> Maybe (a, b)) -> Reagent b
atomicUpdate r f succ fail = do
curTicket <- readForCAS r
let cur = peekTicket curTicket
case f cur of
Just (new, out) -> do
(done, _) <- casIORef r curTicket new
if done then succ out else fail
Nothing -> fail
atomicUpdate_ :: IORef a -> (a -> a) -> Reagent ()
atomicUpdate_ r f = atomicUpdate r (\x -> Just (f x, ()))
postCommit :: Reagent a -> (a -> IO b) -> Reagent b
postCommit r f succ fail = r (\x -> f x >>= succ) fail
choice :: Reagent a -> Reagent a -> Reagent a
choice = error "TODO"