{-|
Module      : Control.Concurrent.STM.Unlift
Licesnse    : BSD-2
Stability   : experimental

Lifted versions of functions from "Control.Concurrent.STM":

* This is meant to be a drop-in replacement for "Control.Concurrent.STM" and
  "UnliftIO.STM", for more streamlined use of 'STM' functions when using
  mtl-style monad transformer stacks.

* Functions that normally return a 'STM' result are abstracted to 'MonadSTM'.
  (Some functions necessarily require the more restrictive 'MonadUnliftSTM'
  typeclass due to 'STM' results appearing in negative positions of the 
  function signature.)

* This module also includes STM-related functions which return an 'IO' result.
  These are abstracted to 'MonadIO' or 'MonadUnliftIO' and are re-exported
  directly from "UnliftIO.STM".

-}

module Control.Concurrent.STM.Unlift
    ( -- * Core
      STM
    , UIO.atomically
    , retry
    , check
    , orElse
    , throwSTM
    , catchSTM
      -- * TVar
    , TVar
    , UIO.newTVarIO
    , UIO.readTVarIO
    , newTVar
    , readTVar
    , writeTVar
    , modifyTVar
    , modifyTVar'
    , modifyTVarM
    , modifyTVarM'
    , swapTVar
    , UIO.registerDelay
    , UIO.mkWeakTVar
      -- * TMVar
    , TMVar
    , newTMVar
    , newEmptyTMVar
    , UIO.newTMVarIO
    , UIO.newEmptyTMVarIO
    , takeTMVar
    , putTMVar
    , readTMVar
    , tryReadTMVar
    , swapTMVar
    , tryTakeTMVar
    , tryPutTMVar
    , isEmptyTMVar
    , UIO.mkWeakTMVar
      -- * TChan
    , TChan
    , newTChan
    , UIO.newTChanIO
    , newBroadcastTChan
    , UIO.newBroadcastTChanIO
    , dupTChan
    , cloneTChan
    , readTChan
    , tryReadTChan
    , peekTChan
    , tryPeekTChan
    , writeTChan
    , unGetTChan
    , isEmptyTChan
      -- * TQueue
    , newTQueue
    , UIO.newTQueueIO
    , readTQueue
    , tryReadTQueue
    , peekTQueue
    , tryPeekTQueue
    , writeTQueue
    , unGetTQueue
    , isEmptyTQueue
      -- * TBQueue
    , newTBQueue
    , UIO.newTBQueueIO
    , readTBQueue
    , tryReadTBQueue
    , peekTBQueue
    , tryPeekTBQueue
    , writeTBQueue
    , unGetTBQueue
    , isEmptyTBQueue
    , isFullTBQueue
      -- * Low-level functions on file descriptors
    , threadWaitReadSTM
    , threadWaitWriteSTM
      -- * Re-exported modules
    , module Control.Monad.STM.Class
    , module Control.Monad.STM.Unlift
    , module Control.Monad.IO.Class
    , module Control.Monad.IO.Unlift
    ) where

import Control.Exception.Base (Exception)
import Control.Monad.IO.Class
import Control.Monad.IO.Unlift
import Control.Monad.STM.Class
import Control.Monad.STM.Unlift
import Data.Bifunctor
import qualified GHC.Conc
import GHC.Natural (Natural)
import System.Posix.Types (Fd)

import           Control.Concurrent.STM (STM, TVar, TMVar, TChan, TQueue, TBQueue)
import qualified Control.Concurrent.STM as STM
import qualified UnliftIO.STM as UIO

-- Core

-- | Lifted version of 'STM.retry'
retry :: MonadSTM m => m a
retry :: m a
retry = STM a -> m a
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM STM a
forall a. STM a
STM.retry

-- | Lifted version of 'STM.check'
check :: MonadSTM m => Bool -> m ()
check :: Bool -> m ()
check = STM () -> m ()
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM () -> m ()) -> (Bool -> STM ()) -> Bool -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> STM ()
STM.check

-- | Lifted version of 'STM.orElse'
orElse :: MonadUnliftSTM m => m a -> m a -> m a
orElse :: m a -> m a -> m a
orElse m a
i m a
t = m (m a -> STM a)
forall (m :: * -> *) a. MonadUnliftSTM m => m (m a -> STM a)
askRunInSTM m (m a -> STM a) -> ((m a -> STM a) -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \m a -> STM a
conv -> STM a -> m a
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM a -> STM a -> STM a
forall a. STM a -> STM a -> STM a
STM.orElse (m a -> STM a
conv m a
i) (m a -> STM a
conv m a
t))

-- | Lifted version of 'STM.throwSTM'
throwSTM :: (Exception e, MonadSTM m) => e -> m a
throwSTM :: e -> m a
throwSTM = STM a -> m a
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM a -> m a) -> (e -> STM a) -> e -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> STM a
forall e a. Exception e => e -> STM a
STM.throwSTM

-- | Lifted version of 'STM.catchSTM'
catchSTM :: (Exception e, MonadUnliftSTM m) => m a -> (e -> m a) -> m a
catchSTM :: m a -> (e -> m a) -> m a
catchSTM m a
m e -> m a
f = m (m a -> STM a)
forall (m :: * -> *) a. MonadUnliftSTM m => m (m a -> STM a)
askRunInSTM m (m a -> STM a) -> ((m a -> STM a) -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \m a -> STM a
conv -> STM a -> m a
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM a -> (e -> STM a) -> STM a
forall e a. Exception e => STM a -> (e -> STM a) -> STM a
STM.catchSTM (m a -> STM a
conv m a
m) (m a -> STM a
conv (m a -> STM a) -> (e -> m a) -> e -> STM a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> m a
f))

-- | Lifted version of 'GHC.Conc.threadWaitReadSTM'
threadWaitReadSTM :: (MonadIO io, MonadSTM stm) => Fd -> io (stm (), io ())
threadWaitReadSTM :: Fd -> io (stm (), io ())
threadWaitReadSTM =
    IO (stm (), io ()) -> io (stm (), io ())
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (stm (), io ()) -> io (stm (), io ()))
-> (Fd -> IO (stm (), io ())) -> Fd -> io (stm (), io ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((STM (), IO ()) -> (stm (), io ()))
-> IO (STM (), IO ()) -> IO (stm (), io ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((STM () -> stm ())
-> (IO () -> io ()) -> (STM (), IO ()) -> (stm (), io ())
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap STM () -> stm ()
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM IO () -> io ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO) (IO (STM (), IO ()) -> IO (stm (), io ()))
-> (Fd -> IO (STM (), IO ())) -> Fd -> IO (stm (), io ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fd -> IO (STM (), IO ())
GHC.Conc.threadWaitReadSTM

-- | Lifted version of 'GHC.Conc.threadWaitWriteSTM'
threadWaitWriteSTM :: (MonadIO io, MonadSTM stm) => Fd -> io (stm (), io ())
threadWaitWriteSTM :: Fd -> io (stm (), io ())
threadWaitWriteSTM =
    IO (stm (), io ()) -> io (stm (), io ())
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (stm (), io ()) -> io (stm (), io ()))
-> (Fd -> IO (stm (), io ())) -> Fd -> io (stm (), io ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((STM (), IO ()) -> (stm (), io ()))
-> IO (STM (), IO ()) -> IO (stm (), io ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((STM () -> stm ())
-> (IO () -> io ()) -> (STM (), IO ()) -> (stm (), io ())
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap STM () -> stm ()
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM IO () -> io ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO) (IO (STM (), IO ()) -> IO (stm (), io ()))
-> (Fd -> IO (STM (), IO ())) -> Fd -> IO (stm (), io ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fd -> IO (STM (), IO ())
GHC.Conc.threadWaitWriteSTM

-- TVar

-- | Lifted version of 'STM.newTVar'
newTVar :: MonadSTM m => a -> m (TVar a)
newTVar :: a -> m (TVar a)
newTVar = STM (TVar a) -> m (TVar a)
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM (TVar a) -> m (TVar a))
-> (a -> STM (TVar a)) -> a -> m (TVar a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> STM (TVar a)
forall a. a -> STM (TVar a)
STM.newTVar

-- | Lifted version of 'STM.readTVar'
readTVar :: MonadSTM m => TVar a -> m a
readTVar :: TVar a -> m a
readTVar = STM a -> m a
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM a -> m a) -> (TVar a -> STM a) -> TVar a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TVar a -> STM a
forall a. TVar a -> STM a
STM.readTVar

-- | Lifted version of 'STM.writeTVar'
writeTVar :: MonadSTM m => TVar a -> a -> m ()
writeTVar :: TVar a -> a -> m ()
writeTVar TVar a
tvar = STM () -> m ()
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM () -> m ()) -> (a -> STM ()) -> a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TVar a -> a -> STM ()
forall a. TVar a -> a -> STM ()
STM.writeTVar TVar a
tvar

-- | Lifted version of 'STM.modifyTVar'
modifyTVar :: MonadSTM m => TVar a -> (a -> a) -> m ()
modifyTVar :: TVar a -> (a -> a) -> m ()
modifyTVar TVar a
tvar = STM () -> m ()
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM () -> m ()) -> ((a -> a) -> STM ()) -> (a -> a) -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TVar a -> (a -> a) -> STM ()
forall a. TVar a -> (a -> a) -> STM ()
STM.modifyTVar TVar a
tvar

-- | Lifted version of 'STM.modifyTVar''
modifyTVar' :: MonadSTM m => TVar a -> (a -> a) -> m ()
modifyTVar' :: TVar a -> (a -> a) -> m ()
modifyTVar' TVar a
tvar = STM () -> m ()
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM () -> m ()) -> ((a -> a) -> STM ()) -> (a -> a) -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TVar a -> (a -> a) -> STM ()
forall a. TVar a -> (a -> a) -> STM ()
STM.modifyTVar' TVar a
tvar

-- | A monadic version of 'modifyTVar'
modifyTVarM :: MonadSTM m => TVar a -> (a -> m a) -> m ()
modifyTVarM :: TVar a -> (a -> m a) -> m ()
modifyTVarM TVar a
tvar a -> m a
f = TVar a -> m a
forall (m :: * -> *) a. MonadSTM m => TVar a -> m a
readTVar TVar a
tvar m a -> (a -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= a -> m a
f m a -> (a -> m ()) -> m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= TVar a -> a -> m ()
forall (m :: * -> *) a. MonadSTM m => TVar a -> a -> m ()
writeTVar TVar a
tvar

-- | A monadic version of 'modifyTVar''
modifyTVarM' :: MonadSTM m => TVar a -> (a -> m a) -> m ()
modifyTVarM' :: TVar a -> (a -> m a) -> m ()
modifyTVarM' TVar a
tvar a -> m a
f = TVar a -> m a
forall (m :: * -> *) a. MonadSTM m => TVar a -> m a
readTVar TVar a
tvar m a -> (a -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= a -> m a
f m a -> (a -> m ()) -> m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
x -> TVar a -> a -> m ()
forall (m :: * -> *) a. MonadSTM m => TVar a -> a -> m ()
writeTVar TVar a
tvar (a -> m ()) -> a -> m ()
forall a b. (a -> b) -> a -> b
$! a
x

-- | Lifted version of 'STM.swapTVar'
swapTVar :: MonadSTM m => TVar a -> a -> m a
swapTVar :: TVar a -> a -> m a
swapTVar TVar a
tvar = STM a -> m a
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM a -> m a) -> (a -> STM a) -> a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TVar a -> a -> STM a
forall a. TVar a -> a -> STM a
STM.swapTVar TVar a
tvar

-- TMVar

-- | Lifted version of 'STM.newTMVar'
newTMVar :: MonadSTM m => a -> m (TMVar a)
newTMVar :: a -> m (TMVar a)
newTMVar = STM (TMVar a) -> m (TMVar a)
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM (TMVar a) -> m (TMVar a))
-> (a -> STM (TMVar a)) -> a -> m (TMVar a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> STM (TMVar a)
forall a. a -> STM (TMVar a)
STM.newTMVar

-- | Lifted version of 'STM.newEmptyTMVar'
newEmptyTMVar :: MonadSTM m => m (TMVar a)
newEmptyTMVar :: m (TMVar a)
newEmptyTMVar = STM (TMVar a) -> m (TMVar a)
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM STM (TMVar a)
forall a. STM (TMVar a)
STM.newEmptyTMVar

-- | Lifted version of 'STM.takeTMVar'
takeTMVar :: MonadSTM m => TMVar a -> m a
takeTMVar :: TMVar a -> m a
takeTMVar = STM a -> m a
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM a -> m a) -> (TMVar a -> STM a) -> TMVar a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TMVar a -> STM a
forall a. TMVar a -> STM a
STM.takeTMVar

-- | Lifted version of 'STM.putTMVar'
putTMVar :: MonadSTM m => TMVar a -> a -> m ()
putTMVar :: TMVar a -> a -> m ()
putTMVar TMVar a
tmvar = STM () -> m ()
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM () -> m ()) -> (a -> STM ()) -> a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TMVar a -> a -> STM ()
forall a. TMVar a -> a -> STM ()
STM.putTMVar TMVar a
tmvar

-- | Lifted version of 'STM.readTMVar'
readTMVar :: MonadSTM m => TMVar a -> m a
readTMVar :: TMVar a -> m a
readTMVar = STM a -> m a
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM a -> m a) -> (TMVar a -> STM a) -> TMVar a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TMVar a -> STM a
forall a. TMVar a -> STM a
STM.readTMVar

-- | Lifted version of 'STM.tryReadTMVar'
tryReadTMVar :: MonadSTM m => TMVar a -> m (Maybe a)
tryReadTMVar :: TMVar a -> m (Maybe a)
tryReadTMVar = STM (Maybe a) -> m (Maybe a)
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM (Maybe a) -> m (Maybe a))
-> (TMVar a -> STM (Maybe a)) -> TMVar a -> m (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TMVar a -> STM (Maybe a)
forall a. TMVar a -> STM (Maybe a)
STM.tryReadTMVar

-- | Lifted version of 'STM.swapTMVar'
swapTMVar :: MonadSTM m => TMVar a -> a -> m a
swapTMVar :: TMVar a -> a -> m a
swapTMVar TMVar a
tmvar = STM a -> m a
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM a -> m a) -> (a -> STM a) -> a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TMVar a -> a -> STM a
forall a. TMVar a -> a -> STM a
STM.swapTMVar TMVar a
tmvar

-- | Lifted version of 'STM.tryTakeTMVar'
tryTakeTMVar :: MonadSTM m => TMVar a -> m (Maybe a)
tryTakeTMVar :: TMVar a -> m (Maybe a)
tryTakeTMVar = STM (Maybe a) -> m (Maybe a)
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM (Maybe a) -> m (Maybe a))
-> (TMVar a -> STM (Maybe a)) -> TMVar a -> m (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TMVar a -> STM (Maybe a)
forall a. TMVar a -> STM (Maybe a)
STM.tryTakeTMVar

-- | Lifted version of 'STM.tryPutTMVar'
tryPutTMVar :: MonadSTM m => TMVar a -> a -> m Bool
tryPutTMVar :: TMVar a -> a -> m Bool
tryPutTMVar TMVar a
tvar = STM Bool -> m Bool
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM Bool -> m Bool) -> (a -> STM Bool) -> a -> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TMVar a -> a -> STM Bool
forall a. TMVar a -> a -> STM Bool
STM.tryPutTMVar TMVar a
tvar

-- | Lifted version of 'STM.isEmptyTMVar'
isEmptyTMVar :: MonadSTM m => TMVar a -> m Bool
isEmptyTMVar :: TMVar a -> m Bool
isEmptyTMVar = STM Bool -> m Bool
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM Bool -> m Bool) -> (TMVar a -> STM Bool) -> TMVar a -> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TMVar a -> STM Bool
forall a. TMVar a -> STM Bool
STM.isEmptyTMVar

-- TChan

-- | Lifted version of 'STM.newTChan'
newTChan :: MonadSTM m => m (TChan a)
newTChan :: m (TChan a)
newTChan = STM (TChan a) -> m (TChan a)
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM STM (TChan a)
forall a. STM (TChan a)
STM.newTChan

-- | Lifted version of 'STM.newBroadcastTChan'
newBroadcastTChan :: MonadSTM m => m (TChan a)
newBroadcastTChan :: m (TChan a)
newBroadcastTChan = STM (TChan a) -> m (TChan a)
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM STM (TChan a)
forall a. STM (TChan a)
STM.newBroadcastTChan

-- | Lifted version of 'STM.dupTChan'
dupTChan :: MonadSTM m => TChan a -> m (TChan a)
dupTChan :: TChan a -> m (TChan a)
dupTChan = STM (TChan a) -> m (TChan a)
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM (TChan a) -> m (TChan a))
-> (TChan a -> STM (TChan a)) -> TChan a -> m (TChan a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TChan a -> STM (TChan a)
forall a. TChan a -> STM (TChan a)
STM.dupTChan

-- | Lifted version of 'STM.cloneTChan'
cloneTChan :: MonadSTM m => TChan a -> m (TChan a)
cloneTChan :: TChan a -> m (TChan a)
cloneTChan = STM (TChan a) -> m (TChan a)
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM (TChan a) -> m (TChan a))
-> (TChan a -> STM (TChan a)) -> TChan a -> m (TChan a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TChan a -> STM (TChan a)
forall a. TChan a -> STM (TChan a)
STM.cloneTChan

-- | Lifted version of 'STM.readTChan'
readTChan :: MonadSTM m => TChan a -> m a
readTChan :: TChan a -> m a
readTChan = STM a -> m a
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM a -> m a) -> (TChan a -> STM a) -> TChan a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TChan a -> STM a
forall a. TChan a -> STM a
STM.readTChan

-- | Lifted version of 'STM.tryReadTChan'
tryReadTChan :: MonadSTM m => TChan a -> m (Maybe a)
tryReadTChan :: TChan a -> m (Maybe a)
tryReadTChan = STM (Maybe a) -> m (Maybe a)
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM (Maybe a) -> m (Maybe a))
-> (TChan a -> STM (Maybe a)) -> TChan a -> m (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TChan a -> STM (Maybe a)
forall a. TChan a -> STM (Maybe a)
STM.tryReadTChan

-- | Lifted version of 'STM.peekTChan'
peekTChan :: MonadSTM m => TChan a -> m a
peekTChan :: TChan a -> m a
peekTChan = STM a -> m a
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM a -> m a) -> (TChan a -> STM a) -> TChan a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TChan a -> STM a
forall a. TChan a -> STM a
STM.peekTChan

-- | Lifted version of 'STM.tryPeekTChan'
tryPeekTChan :: MonadSTM m => TChan a -> m (Maybe a)
tryPeekTChan :: TChan a -> m (Maybe a)
tryPeekTChan = STM (Maybe a) -> m (Maybe a)
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM (Maybe a) -> m (Maybe a))
-> (TChan a -> STM (Maybe a)) -> TChan a -> m (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TChan a -> STM (Maybe a)
forall a. TChan a -> STM (Maybe a)
STM.tryPeekTChan

-- | Lifted version of 'STM.writeTChan'
writeTChan :: MonadSTM m => TChan a -> a -> m ()
writeTChan :: TChan a -> a -> m ()
writeTChan TChan a
tchan = STM () -> m ()
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM () -> m ()) -> (a -> STM ()) -> a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TChan a -> a -> STM ()
forall a. TChan a -> a -> STM ()
STM.writeTChan TChan a
tchan

-- | Lifted version of 'STM.unGetTChan'
unGetTChan :: MonadSTM m => TChan a -> a -> m ()
unGetTChan :: TChan a -> a -> m ()
unGetTChan TChan a
tchan = STM () -> m ()
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM () -> m ()) -> (a -> STM ()) -> a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TChan a -> a -> STM ()
forall a. TChan a -> a -> STM ()
STM.unGetTChan TChan a
tchan

-- | Lifted version of 'STM.isEmptyTChan'
isEmptyTChan :: MonadSTM m => TChan a ->  m Bool
isEmptyTChan :: TChan a -> m Bool
isEmptyTChan = STM Bool -> m Bool
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM Bool -> m Bool) -> (TChan a -> STM Bool) -> TChan a -> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TChan a -> STM Bool
forall a. TChan a -> STM Bool
STM.isEmptyTChan

-- TQueue

-- | Lifted version of 'STM.newTQueue'
newTQueue :: MonadSTM m => m (TQueue a)
newTQueue :: m (TQueue a)
newTQueue = STM (TQueue a) -> m (TQueue a)
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM STM (TQueue a)
forall a. STM (TQueue a)
STM.newTQueue

-- | Lifted version of 'STM.readTQueue'
readTQueue :: MonadSTM m => TQueue a -> m a
readTQueue :: TQueue a -> m a
readTQueue = STM a -> m a
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM a -> m a) -> (TQueue a -> STM a) -> TQueue a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TQueue a -> STM a
forall a. TQueue a -> STM a
STM.readTQueue

-- | Lifted version of 'STM.tryReadTQueue'
tryReadTQueue :: MonadSTM m => TQueue a -> m (Maybe a)
tryReadTQueue :: TQueue a -> m (Maybe a)
tryReadTQueue = STM (Maybe a) -> m (Maybe a)
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM (Maybe a) -> m (Maybe a))
-> (TQueue a -> STM (Maybe a)) -> TQueue a -> m (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TQueue a -> STM (Maybe a)
forall a. TQueue a -> STM (Maybe a)
STM.tryReadTQueue

-- | Lifted version of 'STM.peekTQueue'
peekTQueue :: MonadSTM m => TQueue a -> m a
peekTQueue :: TQueue a -> m a
peekTQueue = STM a -> m a
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM a -> m a) -> (TQueue a -> STM a) -> TQueue a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TQueue a -> STM a
forall a. TQueue a -> STM a
STM.peekTQueue

-- | Lifted version of 'STM.tryPeekTQueue'
tryPeekTQueue :: MonadSTM m => TQueue a -> m (Maybe a)
tryPeekTQueue :: TQueue a -> m (Maybe a)
tryPeekTQueue = STM (Maybe a) -> m (Maybe a)
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM (Maybe a) -> m (Maybe a))
-> (TQueue a -> STM (Maybe a)) -> TQueue a -> m (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TQueue a -> STM (Maybe a)
forall a. TQueue a -> STM (Maybe a)
STM.tryPeekTQueue

-- | Lifted version of 'STM.writeTQueue'
writeTQueue :: MonadSTM m => TQueue a -> a -> m ()
writeTQueue :: TQueue a -> a -> m ()
writeTQueue TQueue a
tchan = STM () -> m ()
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM () -> m ()) -> (a -> STM ()) -> a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TQueue a -> a -> STM ()
forall a. TQueue a -> a -> STM ()
STM.writeTQueue TQueue a
tchan

-- | Lifted version of 'STM.unGetTQueue'
unGetTQueue :: MonadSTM m => TQueue a -> a -> m ()
unGetTQueue :: TQueue a -> a -> m ()
unGetTQueue TQueue a
tchan = STM () -> m ()
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM () -> m ()) -> (a -> STM ()) -> a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TQueue a -> a -> STM ()
forall a. TQueue a -> a -> STM ()
STM.unGetTQueue TQueue a
tchan

-- | Lifted version of 'STM.isEmptyTQueue'
isEmptyTQueue :: MonadSTM m => TQueue a ->  m Bool
isEmptyTQueue :: TQueue a -> m Bool
isEmptyTQueue = STM Bool -> m Bool
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM Bool -> m Bool)
-> (TQueue a -> STM Bool) -> TQueue a -> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TQueue a -> STM Bool
forall a. TQueue a -> STM Bool
STM.isEmptyTQueue

-- TBQueue

-- | Lifted version of 'STM.newTBQueue'
newTBQueue :: MonadSTM m => Natural -> m (TBQueue a)
newTBQueue :: Natural -> m (TBQueue a)
newTBQueue = STM (TBQueue a) -> m (TBQueue a)
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM (TBQueue a) -> m (TBQueue a))
-> (Natural -> STM (TBQueue a)) -> Natural -> m (TBQueue a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Natural -> STM (TBQueue a)
forall a. Natural -> STM (TBQueue a)
STM.newTBQueue

-- | Lifted version of 'STM.readTBQueue'
readTBQueue :: MonadSTM m => TBQueue a -> m a
readTBQueue :: TBQueue a -> m a
readTBQueue = STM a -> m a
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM a -> m a) -> (TBQueue a -> STM a) -> TBQueue a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> STM a
forall a. TBQueue a -> STM a
STM.readTBQueue

-- | Lifted version of 'STM.tryReadTBQueue'
tryReadTBQueue :: MonadSTM m => TBQueue a -> m (Maybe a)
tryReadTBQueue :: TBQueue a -> m (Maybe a)
tryReadTBQueue = STM (Maybe a) -> m (Maybe a)
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM (Maybe a) -> m (Maybe a))
-> (TBQueue a -> STM (Maybe a)) -> TBQueue a -> m (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> STM (Maybe a)
forall a. TBQueue a -> STM (Maybe a)
STM.tryReadTBQueue

-- | Lifted version of 'STM.peekTBQueue'
peekTBQueue :: MonadSTM m => TBQueue a -> m a
peekTBQueue :: TBQueue a -> m a
peekTBQueue = STM a -> m a
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM a -> m a) -> (TBQueue a -> STM a) -> TBQueue a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> STM a
forall a. TBQueue a -> STM a
STM.peekTBQueue

-- | Lifted version of 'STM.tryPeekTBQueue'
tryPeekTBQueue :: MonadSTM m => TBQueue a -> m (Maybe a)
tryPeekTBQueue :: TBQueue a -> m (Maybe a)
tryPeekTBQueue = STM (Maybe a) -> m (Maybe a)
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM (Maybe a) -> m (Maybe a))
-> (TBQueue a -> STM (Maybe a)) -> TBQueue a -> m (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> STM (Maybe a)
forall a. TBQueue a -> STM (Maybe a)
STM.tryPeekTBQueue

-- | Lifted version of 'STM.writeTBQueue'
writeTBQueue :: MonadSTM m => TBQueue a -> a -> m ()
writeTBQueue :: TBQueue a -> a -> m ()
writeTBQueue TBQueue a
tchan = STM () -> m ()
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM () -> m ()) -> (a -> STM ()) -> a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> a -> STM ()
forall a. TBQueue a -> a -> STM ()
STM.writeTBQueue TBQueue a
tchan

-- | Lifted version of 'STM.unGetTBQueue'
unGetTBQueue :: MonadSTM m => TBQueue a -> a -> m ()
unGetTBQueue :: TBQueue a -> a -> m ()
unGetTBQueue TBQueue a
tchan = STM () -> m ()
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM () -> m ()) -> (a -> STM ()) -> a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> a -> STM ()
forall a. TBQueue a -> a -> STM ()
STM.unGetTBQueue TBQueue a
tchan

-- | Lifted version of 'STM.isEmptyTBQueue'
isEmptyTBQueue :: MonadSTM m => TBQueue a ->  m Bool
isEmptyTBQueue :: TBQueue a -> m Bool
isEmptyTBQueue = STM Bool -> m Bool
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM Bool -> m Bool)
-> (TBQueue a -> STM Bool) -> TBQueue a -> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> STM Bool
forall a. TBQueue a -> STM Bool
STM.isEmptyTBQueue

-- | Lifted version of 'STM.isFullTBQueue'
isFullTBQueue :: MonadSTM m => TBQueue a ->  m Bool
isFullTBQueue :: TBQueue a -> m Bool
isFullTBQueue = STM Bool -> m Bool
forall (m :: * -> *) a. MonadSTM m => STM a -> m a
liftSTM (STM Bool -> m Bool)
-> (TBQueue a -> STM Bool) -> TBQueue a -> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> STM Bool
forall a. TBQueue a -> STM Bool
STM.isFullTBQueue