module M.IO.Obs
(
obs,
)
where
import Control.Monad
import Effectful
import Effectful.Concurrent.STM
obs ::
(Concurrent :> es, Eq a) =>
TVar a ->
(a -> a -> STM a) ->
(a -> a -> Eff es ()) ->
Eff es b
obs :: forall (es :: [Effect]) a b.
(Concurrent :> es, Eq a) =>
TVar a -> (a -> a -> STM a) -> (a -> a -> Eff es ()) -> Eff es b
obs TVar a
a a -> a -> STM a
b a -> a -> Eff es ()
c = do
TVar a
old <- TVar a -> Eff es a
forall (es :: [Effect]) a. (Concurrent :> es) => TVar a -> Eff es a
readTVarIO TVar a
a Eff es a -> (a -> Eff es (TVar a)) -> Eff es (TVar a)
forall a b. Eff es a -> (a -> Eff es b) -> Eff es b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= a -> Eff es (TVar a)
forall (es :: [Effect]) a.
(Concurrent :> es) =>
a -> Eff es (TVar a)
newTVarIO
Eff es () -> Eff es b
forall (f :: * -> *) a b. Applicative f => f a -> f b
forever do
(a
ex, a
ez) <- STM (a, a) -> Eff es (a, a)
forall (es :: [Effect]) a. (Concurrent :> es) => STM a -> Eff es a
atomically do
a
x <- TVar a -> STM a
forall a. TVar a -> STM a
readTVar TVar a
old
a
y <- TVar a -> STM a
forall a. TVar a -> STM a
readTVar TVar a
a
Bool -> STM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
y)
a
z <- a -> a -> STM a
b a
x a
y
TVar a -> a -> STM ()
forall a. TVar a -> a -> STM ()
writeTVar TVar a
old a
z
(a, a) -> STM (a, a)
forall a. a -> STM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
x, a
z)
a -> a -> Eff es ()
c a
ex a
ez