module HaskellWorks.Polysemy.Control.Concurrent.STM.TVar
  ( TVar,
    STM.newTVar,
    newTVarIO,
    STM.readTVar,
    readTVarIO,
    STM.writeTVar,
    STM.modifyTVar,
    STM.modifyTVar',
    STM.stateTVar,
    STM.swapTVar,
    registerDelay,
  ) where

import           Control.Concurrent.STM        (TVar)

import qualified Control.Concurrent.STM        as STM
import           Control.Monad.IO.Class        (MonadIO (..))
import           HaskellWorks.Polysemy.Prelude
import           Polysemy

newTVarIO :: forall a r m. ()
  => MonadIO m
  => Member (Embed m) r
  => a
  -> Sem r (TVar a)
newTVarIO :: forall a (r :: EffectRow) (m :: * -> *).
(MonadIO m, Member (Embed m) r) =>
a -> Sem r (TVar a)
newTVarIO a
a = do
  m (TVar a) -> Sem r (TVar a)
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (m (TVar a) -> Sem r (TVar a)) -> m (TVar a) -> Sem r (TVar a)
forall a b. (a -> b) -> a -> b
$ IO (TVar a) -> m (TVar a)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (TVar a) -> m (TVar a)) -> IO (TVar a) -> m (TVar a)
forall a b. (a -> b) -> a -> b
$ a -> IO (TVar a)
forall a. a -> IO (TVar a)
STM.newTVarIO a
a

readTVarIO :: forall a r m. ()
  => MonadIO m
  => Member (Embed m) r
  => TVar a
  -> Sem r a
readTVarIO :: forall a (r :: EffectRow) (m :: * -> *).
(MonadIO m, Member (Embed m) r) =>
TVar a -> Sem r a
readTVarIO TVar a
tvar = do
  m a -> Sem r a
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (m a -> Sem r a) -> m a -> Sem r a
forall a b. (a -> b) -> a -> b
$ IO a -> m a
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> m a) -> IO a -> m a
forall a b. (a -> b) -> a -> b
$ TVar a -> IO a
forall a. TVar a -> IO a
STM.readTVarIO TVar a
tvar

registerDelay :: forall r m. ()
  => MonadIO m
  => Member (Embed m) r
  => Int
  -> Sem r (TVar Bool)
registerDelay :: forall (r :: EffectRow) (m :: * -> *).
(MonadIO m, Member (Embed m) r) =>
Int -> Sem r (TVar Bool)
registerDelay Int
n = do
  m (TVar Bool) -> Sem r (TVar Bool)
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (m (TVar Bool) -> Sem r (TVar Bool))
-> m (TVar Bool) -> Sem r (TVar Bool)
forall a b. (a -> b) -> a -> b
$ IO (TVar Bool) -> m (TVar Bool)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (TVar Bool) -> m (TVar Bool))
-> IO (TVar Bool) -> m (TVar Bool)
forall a b. (a -> b) -> a -> b
$ Int -> IO (TVar Bool)
STM.registerDelay Int
n