{-# LANGUAGE CPP #-}

-- | Provides the 'MonadThread' typeclass.
--
-- @since 0.1
module Effects.Concurrent.Thread
  ( -- * Thread Effect
    MonadThread (..),
    microsleep,
    sleep,

    -- ** Reexports
    Natural,
    ThreadId,

    -- * MVar Effect
    MonadMVar (..),

    -- ** Reexports
    MVar,

    -- * QSem Effect
    MonadQSem (..),
    MonadQSemN (..),

    -- ** Reexports
    QSem,
    QSemN,
  )
where

import Control.Concurrent (ThreadId)
import Control.Concurrent qualified as CC
import Control.Concurrent.MVar (MVar)
import Control.Concurrent.MVar qualified as MVar
import Control.Concurrent.QSem (QSem)
import Control.Concurrent.QSem qualified as QSem
import Control.Concurrent.QSemN (QSemN)
import Control.Concurrent.QSemN qualified as QSemN
import Control.Exception (Exception, evaluate)
import Control.Monad ((>=>))
import Control.Monad.Trans.Class (MonadTrans (lift))
import Control.Monad.Trans.Reader (ReaderT (runReaderT), ask)
import Data.Foldable (for_)
import GHC.Conc.Sync qualified as Sync
import GHC.Natural (Natural)
import GHC.Stack (HasCallStack)
import System.Mem.Weak (Weak)

{- ORMOLU_DISABLE -}

-- | Represents thread effects.
--
-- @since 0.1
class (Monad m) => MonadThread m where
  -- | Lifted 'CC.threadDelay'.
  --
  -- @since 0.1
  threadDelay :: (HasCallStack) => Int -> m ()

  -- | Lifted 'CC.throwTo'.
  --
  -- @since 0.1
  throwTo :: (Exception e, HasCallStack) => ThreadId -> e -> m ()

  -- | Lifted 'CC.getNumCapabilities'.
  --
  -- @since 0.1
  getNumCapabilities :: (HasCallStack) => m Int

  -- | Lifted 'CC.setNumCapabilities'.
  --
  -- @since 0.1
  setNumCapabilities :: (HasCallStack) => Int -> m ()

  -- | Lifted 'CC.threadCapability'.
  --
  -- @since 0.1
  threadCapability :: (HasCallStack) => ThreadId -> m (Int, Bool)

  -- | Lifted 'CC.myThreadId'.
  --
  -- @since 0.1
  myThreadId :: (HasCallStack) => m ThreadId

  -- | Lifted 'Sync.labelThread'.
  --
  -- @since 0.1
  labelThread :: (HasCallStack) => ThreadId -> String -> m ()

#if MIN_VERSION_base(4, 18, 0)

  -- | Lifted 'Sync.threadLabel'.
  --
  -- @since 0.1
  threadLabel :: (HasCallStack) => ThreadId -> m (Maybe String)

#endif

-- | @since 0.1
instance MonadThread IO where
  threadDelay :: HasCallStack => Int -> IO ()
threadDelay = Int -> IO ()
CC.threadDelay
  {-# INLINEABLE threadDelay #-}
  throwTo :: forall e. (Exception e, HasCallStack) => ThreadId -> e -> IO ()
throwTo = ThreadId -> e -> IO ()
forall e. Exception e => ThreadId -> e -> IO ()
CC.throwTo
  {-# INLINEABLE throwTo #-}
  getNumCapabilities :: HasCallStack => IO Int
getNumCapabilities = IO Int
CC.getNumCapabilities
  {-# INLINEABLE getNumCapabilities #-}
  setNumCapabilities :: HasCallStack => Int -> IO ()
setNumCapabilities = Int -> IO ()
CC.setNumCapabilities
  {-# INLINEABLE setNumCapabilities #-}
  threadCapability :: HasCallStack => ThreadId -> IO (Int, Bool)
threadCapability = ThreadId -> IO (Int, Bool)
CC.threadCapability
  {-# INLINEABLE threadCapability #-}
  myThreadId :: HasCallStack => IO ThreadId
myThreadId = IO ThreadId
CC.myThreadId
  {-# INLINEABLE myThreadId #-}
  labelThread :: HasCallStack => ThreadId -> String -> IO ()
labelThread = ThreadId -> String -> IO ()
Sync.labelThread
  {-# INLINEABLE labelThread #-}
#if MIN_VERSION_base(4, 18, 0)
  threadLabel :: HasCallStack => ThreadId -> IO (Maybe String)
threadLabel = ThreadId -> IO (Maybe String)
Sync.threadLabel
  {-# INLINEABLE threadLabel #-}
#endif

-- | @since 0.1
instance (MonadThread m) => MonadThread (ReaderT e m) where
  threadDelay :: HasCallStack => Int -> ReaderT e m ()
threadDelay = m () -> ReaderT e m ()
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT e m ()) -> (Int -> m ()) -> Int -> ReaderT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> m ()
forall (m :: * -> *). (MonadThread m, HasCallStack) => Int -> m ()
threadDelay
  {-# INLINEABLE threadDelay #-}
  throwTo :: forall e.
(Exception e, HasCallStack) =>
ThreadId -> e -> ReaderT e m ()
throwTo ThreadId
tid = m () -> ReaderT e m ()
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT e m ()) -> (e -> m ()) -> e -> ReaderT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ThreadId -> e -> m ()
forall e. (Exception e, HasCallStack) => ThreadId -> e -> m ()
forall (m :: * -> *) e.
(MonadThread m, Exception e, HasCallStack) =>
ThreadId -> e -> m ()
throwTo ThreadId
tid
  {-# INLINEABLE throwTo #-}
  getNumCapabilities :: HasCallStack => ReaderT e m Int
getNumCapabilities = m Int -> ReaderT e m Int
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m Int
forall (m :: * -> *). (MonadThread m, HasCallStack) => m Int
getNumCapabilities
  {-# INLINEABLE getNumCapabilities #-}
  setNumCapabilities :: HasCallStack => Int -> ReaderT e m ()
setNumCapabilities = m () -> ReaderT e m ()
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT e m ()) -> (Int -> m ()) -> Int -> ReaderT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> m ()
forall (m :: * -> *). (MonadThread m, HasCallStack) => Int -> m ()
setNumCapabilities
  {-# INLINEABLE setNumCapabilities #-}
  threadCapability :: HasCallStack => ThreadId -> ReaderT e m (Int, Bool)
threadCapability = m (Int, Bool) -> ReaderT e m (Int, Bool)
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Int, Bool) -> ReaderT e m (Int, Bool))
-> (ThreadId -> m (Int, Bool))
-> ThreadId
-> ReaderT e m (Int, Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ThreadId -> m (Int, Bool)
forall (m :: * -> *).
(MonadThread m, HasCallStack) =>
ThreadId -> m (Int, Bool)
threadCapability
  {-# INLINEABLE threadCapability #-}
  myThreadId :: HasCallStack => ReaderT e m ThreadId
myThreadId = m ThreadId -> ReaderT e m ThreadId
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m ThreadId
forall (m :: * -> *). (MonadThread m, HasCallStack) => m ThreadId
myThreadId
  {-# INLINEABLE myThreadId #-}
  labelThread :: HasCallStack => ThreadId -> String -> ReaderT e m ()
labelThread ThreadId
tid = m () -> ReaderT e m ()
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT e m ())
-> (String -> m ()) -> String -> ReaderT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ThreadId -> String -> m ()
forall (m :: * -> *).
(MonadThread m, HasCallStack) =>
ThreadId -> String -> m ()
labelThread ThreadId
tid
  {-# INLINEABLE labelThread #-}
#if MIN_VERSION_base(4, 18, 0)
  threadLabel :: HasCallStack => ThreadId -> ReaderT e m (Maybe String)
threadLabel = m (Maybe String) -> ReaderT e m (Maybe String)
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe String) -> ReaderT e m (Maybe String))
-> (ThreadId -> m (Maybe String))
-> ThreadId
-> ReaderT e m (Maybe String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ThreadId -> m (Maybe String)
forall (m :: * -> *).
(MonadThread m, HasCallStack) =>
ThreadId -> m (Maybe String)
threadLabel
  {-# INLINEABLE threadLabel #-}
#endif

{- ORMOLU_ENABLE -}

-- | 'threadDelay' in terms of unbounded 'Natural' rather than 'Int' i.e.
-- runs sleep in the current thread for the specified number of microseconds.
--
-- @since 0.1
microsleep :: (HasCallStack, MonadThread m) => Natural -> m ()
microsleep :: forall (m :: * -> *).
(HasCallStack, MonadThread m) =>
Natural -> m ()
microsleep Natural
n = [Int] -> (Int -> m ()) -> m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ (Natural -> [Int]
natToInts Natural
n) Int -> m ()
forall (m :: * -> *). (MonadThread m, HasCallStack) => Int -> m ()
threadDelay
{-# INLINEABLE microsleep #-}

-- | Runs sleep in the current thread for the specified number of
-- seconds.
--
-- @since 0.1
sleep :: (HasCallStack, MonadThread m) => Natural -> m ()
sleep :: forall (m :: * -> *).
(HasCallStack, MonadThread m) =>
Natural -> m ()
sleep = Natural -> m ()
forall (m :: * -> *).
(HasCallStack, MonadThread m) =>
Natural -> m ()
microsleep (Natural -> m ()) -> (Natural -> Natural) -> Natural -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Natural -> Natural -> Natural
forall a. Num a => a -> a -> a
* Natural
1_000_000)
{-# INLINEABLE sleep #-}

natToInts :: Natural -> [Int]
natToInts :: Natural -> [Int]
natToInts Natural
n
  | Natural
n Natural -> Natural -> Bool
forall a. Ord a => a -> a -> Bool
> Natural
maxIntAsNat = Int
maxInt Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: Natural -> [Int]
natToInts (Natural
n Natural -> Natural -> Natural
forall a. Num a => a -> a -> a
- Natural
maxIntAsNat)
  | Bool
otherwise = [Natural -> Int
n2i Natural
n]
  where
    maxInt :: Int
    maxInt :: Int
maxInt = Int
forall a. Bounded a => a
maxBound
    maxIntAsNat :: Natural
    maxIntAsNat :: Natural
maxIntAsNat = Int -> Natural
i2n Int
maxInt

n2i :: Natural -> Int
n2i :: Natural -> Int
n2i = Natural -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral

i2n :: Int -> Natural
i2n :: Int -> Natural
i2n = Int -> Natural
forall a b. (Integral a, Num b) => a -> b
fromIntegral

-- NOTE: [Strictness design]
--
-- We want to provide strict (WHNF) versions of mutable functions to prevent
-- space leaks.
--
-- 1. First, there is a choice for evaluation:
--
--      a. Put strict functions in typeclass, use @evaluate :: a -> IO a@
--         in instance.
--
--      b. Use @(MonadEvaluate m) => evaluate :: a -> m a@ outside of typeclass.
--
--    A has the advantage that we do not need a MonadEvaluate dependency, and
--    we can simply reuse upstream definitions (e.g. modifyIORef') when they
--    exist.
--
--    B keeps the typeclass smaller. The main downside is that if upstream ever
--    adds a strict function -- which we should prefer over bespoke definitions
--    here -- then we could get in an awkward position where the lifted
--    upstream definition is in the typeclass, but other strict functions are
--    not (hence difference in MonadEvaluate constraint).
--
--    For that reason, and the fact that we may not be able to implement some
--    outside of the typeclass (e.g. hypothetical mkWeakMVar' requires IO), we
--    decide to put everything in the typeclass.
--
-- 2. Next, we have a choice of what WHNF actually means. At the very least
--    we want the values held by our mutable references to be in WHNF e.g.
--    the @a@ in @MVar a@.
--
--    But we have other choices too. Do we evaluate the output (@a@) of, say,
--    takeMVar? What about non-polymorphic values like @tryPutMVar@ returning
--    Bool? Finally, what about functions like @newEmptyMVar@ that have no
--    WHNF analog? Make a ticked alias or do nothing?
--
--    We take the principle that ticked functions should act as if the
--    underlying reference was strict e.g. (MVar a = MVar !a). Hence
--    we eval when writing and reading this value, but do not eval anything
--    else. We also do not include ticked aliases that do nothing.
--
--    See the following proposal for more details, and hopefully a more
--    robust plan in the future:
--
--      https://github.com/haskell/core-libraries-committee/issues/341

-- | Effect for 'MVar'.
--
-- @since 0.1
class (Monad m) => MonadMVar m where
  -- | Lifted 'MVar.newEmptyMVar'.
  --
  -- @since 0.1
  newEmptyMVar :: m (MVar a)

  -- | Lifted 'MVar.newMVar'.
  --
  -- @since 0.1
  newMVar :: a -> m (MVar a)

  -- | Evaluates the input to 'newMVar' to WHNF.
  --
  -- @since 0.1
  newMVar' :: a -> m (MVar a)

  -- | Lifted 'MVar.takeMVar'.
  --
  -- @since 0.1
  takeMVar :: MVar a -> m a

  -- | Evaluates the output of 'takeMVar' to WHNF.
  --
  -- @since 0.1
  takeMVar' :: MVar a -> m a

  -- | Lifted 'MVar.putMVar'.
  --
  -- @since 0.1
  putMVar :: MVar a -> a -> m ()

  -- | Evaluates the input to 'putMVar' to WHNF.
  --
  -- @since 0.1
  putMVar' :: MVar a -> a -> m ()

  -- | Lifted 'MVar.tryTakeMVar'.
  --
  -- @since 0.1
  tryTakeMVar :: MVar a -> m (Maybe a)

  -- | Evaluates the output of 'tryTakeMVar' to Nothing or @Just a@, where
  -- @a@ is in WHNF.
  --
  -- @since 0.1
  tryTakeMVar' :: MVar a -> m (Maybe a)

  -- | Lifted 'MVar.tryPutMVar'.
  --
  -- @since 0.1
  tryPutMVar :: MVar a -> a -> m Bool

  -- | Evaluates the input to 'tryPutMVar' to WHNF.
  --
  -- @since 0.1
  tryPutMVar' :: MVar a -> a -> m Bool

  -- | Lifted 'MVar.isEmptyMVar'.
  --
  -- @since 0.1
  isEmptyMVar :: MVar a -> m Bool

  -- | Lifted 'MVar.withMVar'.
  --
  -- @since 0.1
  withMVar :: MVar a -> (a -> m b) -> m b

  -- | Evaluates the input of the callback to 'withMVar' to WHNF.
  --
  -- @since 0.1
  withMVar' :: MVar a -> (a -> m b) -> m b

  -- | Lifted 'MVar.withMVarMasked'.
  --
  -- @since 0.1
  withMVarMasked :: MVar a -> (a -> m b) -> m b

  -- | Evaluates the input of the callback to 'withMVarMasked' to WHNF.
  --
  -- @since 0.1
  withMVarMasked' :: MVar a -> (a -> m b) -> m b

  -- | Lifted 'MVar.modifyMVar_'.
  --
  -- @since 0.1
  modifyMVar_ :: MVar a -> (a -> m a) -> m ()

  -- | Evaluates 'modifyMVar_'\'s modifier's input and output to WHNF.
  --
  -- @since 0.1
  modifyMVar_' :: MVar a -> (a -> m a) -> m ()

  -- | Lifted 'MVar.modifyMVar'.
  --
  -- @since 0.1
  modifyMVar :: MVar a -> (a -> m (a, b)) -> m b

  -- | Evaluates 'modifyMVar'\'s modifier's input and left-output to WHNF.
  --
  -- @since 0.1
  modifyMVar' :: MVar a -> (a -> m (a, b)) -> m b

  -- | Lifted 'MVar.modifyMVarMasked_'.
  --
  -- @since 0.1
  modifyMVarMasked_ :: MVar a -> (a -> m a) -> m ()

  -- | Evaluates 'modifyMVarMasked_'\'s modifier's input and output to WHNF.
  --
  -- @since 0.1
  modifyMVarMasked_' :: MVar a -> (a -> m a) -> m ()

  -- | Lifted 'MVar.modifyMVarMasked'.
  --
  -- @since 0.1
  modifyMVarMasked :: MVar a -> (a -> m (a, b)) -> m b

  -- | Evaluates 'modifyMVarMasked'\'s modifier's input and left-output to WHNF.
  --
  -- @since 0.1
  modifyMVarMasked' :: MVar a -> (a -> m (a, b)) -> m b

  -- | Lifted 'MVar.tryReadMVar'.
  --
  -- @since 0.1
  tryReadMVar :: MVar a -> m (Maybe a)

  -- | Evaluates the output of 'tryReadMVar' to Nothing or @Just a@, where
  -- @a@ is in WHNF.
  --
  -- @since 0.1
  tryReadMVar' :: MVar a -> m (Maybe a)

  -- | Lifted 'MVar.mkWeakMVar'.
  --
  -- @since 0.1
  mkWeakMVar :: MVar a -> m () -> m (Weak (MVar a))

-- | @since 0.1
instance MonadMVar IO where
  newEmptyMVar :: forall a. IO (MVar a)
newEmptyMVar = IO (MVar a)
forall a. IO (MVar a)
MVar.newEmptyMVar
  {-# INLINEABLE newEmptyMVar #-}

  newMVar :: forall a. a -> IO (MVar a)
newMVar = a -> IO (MVar a)
forall a. a -> IO (MVar a)
MVar.newMVar
  {-# INLINEABLE newMVar #-}

  newMVar' :: forall a. a -> IO (MVar a)
newMVar' = a -> IO a
forall a. a -> IO a
evaluate (a -> IO a) -> (a -> IO (MVar a)) -> a -> IO (MVar a)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> a -> IO (MVar a)
forall a. a -> IO (MVar a)
forall (m :: * -> *) a. MonadMVar m => a -> m (MVar a)
newMVar
  {-# INLINEABLE newMVar' #-}

  takeMVar :: forall a. MVar a -> IO a
takeMVar = MVar a -> IO a
forall a. MVar a -> IO a
MVar.takeMVar
  {-# INLINEABLE takeMVar #-}

  takeMVar' :: forall a. MVar a -> IO a
takeMVar' = MVar a -> IO a
forall a. MVar a -> IO a
forall (m :: * -> *) a. MonadMVar m => MVar a -> m a
takeMVar (MVar a -> IO a) -> (a -> IO a) -> MVar a -> IO a
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> a -> IO a
forall a. a -> IO a
evaluate
  {-# INLINEABLE takeMVar' #-}

  putMVar :: forall a. MVar a -> a -> IO ()
putMVar = MVar a -> a -> IO ()
forall a. MVar a -> a -> IO ()
MVar.putMVar
  {-# INLINEABLE putMVar #-}

  putMVar' :: forall a. MVar a -> a -> IO ()
putMVar' MVar a
v = a -> IO a
forall a. a -> IO a
evaluate (a -> IO a) -> (a -> IO ()) -> a -> IO ()
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> MVar a -> a -> IO ()
forall a. MVar a -> a -> IO ()
forall (m :: * -> *) a. MonadMVar m => MVar a -> a -> m ()
putMVar MVar a
v
  {-# INLINEABLE putMVar' #-}

  tryTakeMVar :: forall a. MVar a -> IO (Maybe a)
tryTakeMVar = MVar a -> IO (Maybe a)
forall a. MVar a -> IO (Maybe a)
MVar.tryTakeMVar
  {-# INLINEABLE tryTakeMVar #-}

  tryTakeMVar' :: forall a. MVar a -> IO (Maybe a)
tryTakeMVar' MVar a
v =
    MVar a -> IO (Maybe a)
forall a. MVar a -> IO (Maybe a)
forall (m :: * -> *) a. MonadMVar m => MVar a -> m (Maybe a)
tryTakeMVar MVar a
v IO (Maybe a) -> (Maybe a -> IO (Maybe a)) -> IO (Maybe a)
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      Maybe a
Nothing -> Maybe a -> IO (Maybe a)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
forall a. Maybe a
Nothing
      Just a
x -> a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> IO a -> IO (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> IO a
forall a. a -> IO a
evaluate a
x
  {-# INLINEABLE tryTakeMVar' #-}

  tryPutMVar :: forall a. MVar a -> a -> IO Bool
tryPutMVar = MVar a -> a -> IO Bool
forall a. MVar a -> a -> IO Bool
MVar.tryPutMVar
  {-# INLINEABLE tryPutMVar #-}

  tryPutMVar' :: forall a. MVar a -> a -> IO Bool
tryPutMVar' MVar a
v = a -> IO a
forall a. a -> IO a
evaluate (a -> IO a) -> (a -> IO Bool) -> a -> IO Bool
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> MVar a -> a -> IO Bool
forall a. MVar a -> a -> IO Bool
forall (m :: * -> *) a. MonadMVar m => MVar a -> a -> m Bool
tryPutMVar MVar a
v
  {-# INLINEABLE tryPutMVar' #-}

  isEmptyMVar :: forall a. MVar a -> IO Bool
isEmptyMVar = MVar a -> IO Bool
forall a. MVar a -> IO Bool
MVar.isEmptyMVar
  {-# INLINEABLE isEmptyMVar #-}

  withMVar :: forall a b. MVar a -> (a -> IO b) -> IO b
withMVar = MVar a -> (a -> IO b) -> IO b
forall a b. MVar a -> (a -> IO b) -> IO b
MVar.withMVar
  {-# INLINEABLE withMVar #-}

  withMVar' :: forall a b. MVar a -> (a -> IO b) -> IO b
withMVar' MVar a
v a -> IO b
f = MVar a -> (a -> IO b) -> IO b
forall a b. MVar a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b.
MonadMVar m =>
MVar a -> (a -> m b) -> m b
withMVar MVar a
v (a -> IO a
forall a. a -> IO a
evaluate (a -> IO a) -> (a -> IO b) -> a -> IO b
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> a -> IO b
f)
  {-# INLINEABLE withMVar' #-}

  withMVarMasked :: forall a b. MVar a -> (a -> IO b) -> IO b
withMVarMasked = MVar a -> (a -> IO b) -> IO b
forall a b. MVar a -> (a -> IO b) -> IO b
MVar.withMVarMasked
  {-# INLINEABLE withMVarMasked #-}

  withMVarMasked' :: forall a b. MVar a -> (a -> IO b) -> IO b
withMVarMasked' MVar a
v a -> IO b
f = MVar a -> (a -> IO b) -> IO b
forall a b. MVar a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b.
MonadMVar m =>
MVar a -> (a -> m b) -> m b
withMVarMasked MVar a
v (a -> IO a
forall a. a -> IO a
evaluate (a -> IO a) -> (a -> IO b) -> a -> IO b
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> a -> IO b
f)
  {-# INLINEABLE withMVarMasked' #-}

  modifyMVar_ :: forall a. MVar a -> (a -> IO a) -> IO ()
modifyMVar_ = MVar a -> (a -> IO a) -> IO ()
forall a. MVar a -> (a -> IO a) -> IO ()
MVar.modifyMVar_
  {-# INLINEABLE modifyMVar_ #-}

  modifyMVar_' :: forall a. MVar a -> (a -> IO a) -> IO ()
modifyMVar_' MVar a
v a -> IO a
f = MVar a -> (a -> IO a) -> IO ()
forall a. MVar a -> (a -> IO a) -> IO ()
forall (m :: * -> *) a. MonadMVar m => MVar a -> (a -> m a) -> m ()
modifyMVar_ MVar a
v (a -> IO a
f (a -> IO a) -> (a -> IO a) -> a -> IO a
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> a -> IO a
forall a. a -> IO a
evaluate)
  {-# INLINEABLE modifyMVar_' #-}

  modifyMVar :: forall a b. MVar a -> (a -> IO (a, b)) -> IO b
modifyMVar = MVar a -> (a -> IO (a, b)) -> IO b
forall a b. MVar a -> (a -> IO (a, b)) -> IO b
MVar.modifyMVar
  {-# INLINEABLE modifyMVar #-}

  modifyMVar' :: forall a b. MVar a -> (a -> IO (a, b)) -> IO b
modifyMVar' MVar a
v a -> IO (a, b)
f = MVar a -> (a -> IO (a, b)) -> IO b
forall a b. MVar a -> (a -> IO (a, b)) -> IO b
forall (m :: * -> *) a b.
MonadMVar m =>
MVar a -> (a -> m (a, b)) -> m b
modifyMVar MVar a
v ((a -> IO (a, b)) -> IO b) -> (a -> IO (a, b)) -> IO b
forall a b. (a -> b) -> a -> b
$ \a
x -> do
    (a, b) <- a -> IO (a, b)
f a
x
    (,b) <$> evaluate a
  {-# INLINEABLE modifyMVar' #-}

  modifyMVarMasked_ :: forall a. MVar a -> (a -> IO a) -> IO ()
modifyMVarMasked_ = MVar a -> (a -> IO a) -> IO ()
forall a. MVar a -> (a -> IO a) -> IO ()
MVar.modifyMVarMasked_
  {-# INLINEABLE modifyMVarMasked_ #-}

  modifyMVarMasked_' :: forall a. MVar a -> (a -> IO a) -> IO ()
modifyMVarMasked_' MVar a
v a -> IO a
f = MVar a -> (a -> IO a) -> IO ()
forall a. MVar a -> (a -> IO a) -> IO ()
forall (m :: * -> *) a. MonadMVar m => MVar a -> (a -> m a) -> m ()
modifyMVarMasked_ MVar a
v (a -> IO a
f (a -> IO a) -> (a -> IO a) -> a -> IO a
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> a -> IO a
forall a. a -> IO a
evaluate)
  {-# INLINEABLE modifyMVarMasked_' #-}

  modifyMVarMasked :: forall a b. MVar a -> (a -> IO (a, b)) -> IO b
modifyMVarMasked = MVar a -> (a -> IO (a, b)) -> IO b
forall a b. MVar a -> (a -> IO (a, b)) -> IO b
MVar.modifyMVarMasked
  {-# INLINEABLE modifyMVarMasked #-}

  modifyMVarMasked' :: forall a b. MVar a -> (a -> IO (a, b)) -> IO b
modifyMVarMasked' MVar a
v a -> IO (a, b)
f = MVar a -> (a -> IO (a, b)) -> IO b
forall a b. MVar a -> (a -> IO (a, b)) -> IO b
forall (m :: * -> *) a b.
MonadMVar m =>
MVar a -> (a -> m (a, b)) -> m b
modifyMVarMasked MVar a
v ((a -> IO (a, b)) -> IO b) -> (a -> IO (a, b)) -> IO b
forall a b. (a -> b) -> a -> b
$ \a
x -> do
    (a, b) <- a -> IO (a, b)
f a
x
    (,b) <$> evaluate a
  {-# INLINEABLE modifyMVarMasked' #-}

  tryReadMVar :: forall a. MVar a -> IO (Maybe a)
tryReadMVar = MVar a -> IO (Maybe a)
forall a. MVar a -> IO (Maybe a)
MVar.tryReadMVar
  {-# INLINEABLE tryReadMVar #-}

  tryReadMVar' :: forall a. MVar a -> IO (Maybe a)
tryReadMVar' MVar a
v =
    MVar a -> IO (Maybe a)
forall a. MVar a -> IO (Maybe a)
forall (m :: * -> *) a. MonadMVar m => MVar a -> m (Maybe a)
tryReadMVar MVar a
v IO (Maybe a) -> (Maybe a -> IO (Maybe a)) -> IO (Maybe a)
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      Maybe a
Nothing -> Maybe a -> IO (Maybe a)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
forall a. Maybe a
Nothing
      Just a
x -> a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> IO a -> IO (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> IO a
forall a. a -> IO a
evaluate a
x
  {-# INLINEABLE tryReadMVar' #-}

  mkWeakMVar :: forall a. MVar a -> IO () -> IO (Weak (MVar a))
mkWeakMVar = MVar a -> IO () -> IO (Weak (MVar a))
forall a. MVar a -> IO () -> IO (Weak (MVar a))
MVar.mkWeakMVar
  {-# INLINEABLE mkWeakMVar #-}

-- | @since 0.1
instance (MonadMVar m) => MonadMVar (ReaderT e m) where
  newEmptyMVar :: forall a. ReaderT e m (MVar a)
newEmptyMVar = m (MVar a) -> ReaderT e m (MVar a)
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m (MVar a)
forall a. m (MVar a)
forall (m :: * -> *) a. MonadMVar m => m (MVar a)
newEmptyMVar
  {-# INLINEABLE newEmptyMVar #-}
  newMVar :: forall a. a -> ReaderT e m (MVar a)
newMVar = m (MVar a) -> ReaderT e m (MVar a)
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (MVar a) -> ReaderT e m (MVar a))
-> (a -> m (MVar a)) -> a -> ReaderT e m (MVar a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m (MVar a)
forall a. a -> m (MVar a)
forall (m :: * -> *) a. MonadMVar m => a -> m (MVar a)
newMVar
  {-# INLINEABLE newMVar #-}
  newMVar' :: forall a. a -> ReaderT e m (MVar a)
newMVar' = m (MVar a) -> ReaderT e m (MVar a)
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (MVar a) -> ReaderT e m (MVar a))
-> (a -> m (MVar a)) -> a -> ReaderT e m (MVar a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m (MVar a)
forall a. a -> m (MVar a)
forall (m :: * -> *) a. MonadMVar m => a -> m (MVar a)
newMVar'
  {-# INLINEABLE newMVar' #-}
  takeMVar :: forall a. MVar a -> ReaderT e m a
takeMVar = m a -> ReaderT e m a
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> ReaderT e m a)
-> (MVar a -> m a) -> MVar a -> ReaderT e m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> m a
forall a. MVar a -> m a
forall (m :: * -> *) a. MonadMVar m => MVar a -> m a
takeMVar
  {-# INLINEABLE takeMVar #-}
  takeMVar' :: forall a. MVar a -> ReaderT e m a
takeMVar' = m a -> ReaderT e m a
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> ReaderT e m a)
-> (MVar a -> m a) -> MVar a -> ReaderT e m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> m a
forall a. MVar a -> m a
forall (m :: * -> *) a. MonadMVar m => MVar a -> m a
takeMVar'
  {-# INLINEABLE takeMVar' #-}
  putMVar :: forall a. MVar a -> a -> ReaderT e m ()
putMVar MVar a
x1 = m () -> ReaderT e m ()
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT e m ()) -> (a -> m ()) -> a -> ReaderT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> a -> m ()
forall a. MVar a -> a -> m ()
forall (m :: * -> *) a. MonadMVar m => MVar a -> a -> m ()
putMVar MVar a
x1
  {-# INLINEABLE putMVar #-}
  putMVar' :: forall a. MVar a -> a -> ReaderT e m ()
putMVar' MVar a
x1 = m () -> ReaderT e m ()
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT e m ()) -> (a -> m ()) -> a -> ReaderT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> a -> m ()
forall a. MVar a -> a -> m ()
forall (m :: * -> *) a. MonadMVar m => MVar a -> a -> m ()
putMVar' MVar a
x1
  {-# INLINEABLE putMVar' #-}
  tryTakeMVar :: forall a. MVar a -> ReaderT e m (Maybe a)
tryTakeMVar = m (Maybe a) -> ReaderT e m (Maybe a)
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe a) -> ReaderT e m (Maybe a))
-> (MVar a -> m (Maybe a)) -> MVar a -> ReaderT e m (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> m (Maybe a)
forall a. MVar a -> m (Maybe a)
forall (m :: * -> *) a. MonadMVar m => MVar a -> m (Maybe a)
tryTakeMVar
  {-# INLINEABLE tryTakeMVar #-}
  tryTakeMVar' :: forall a. MVar a -> ReaderT e m (Maybe a)
tryTakeMVar' = m (Maybe a) -> ReaderT e m (Maybe a)
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe a) -> ReaderT e m (Maybe a))
-> (MVar a -> m (Maybe a)) -> MVar a -> ReaderT e m (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> m (Maybe a)
forall a. MVar a -> m (Maybe a)
forall (m :: * -> *) a. MonadMVar m => MVar a -> m (Maybe a)
tryTakeMVar'
  {-# INLINEABLE tryTakeMVar' #-}
  tryPutMVar :: forall a. MVar a -> a -> ReaderT e m Bool
tryPutMVar MVar a
x1 = m Bool -> ReaderT e m Bool
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m Bool -> ReaderT e m Bool)
-> (a -> m Bool) -> a -> ReaderT e m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> a -> m Bool
forall a. MVar a -> a -> m Bool
forall (m :: * -> *) a. MonadMVar m => MVar a -> a -> m Bool
tryPutMVar MVar a
x1
  {-# INLINEABLE tryPutMVar #-}
  tryPutMVar' :: forall a. MVar a -> a -> ReaderT e m Bool
tryPutMVar' MVar a
x1 = m Bool -> ReaderT e m Bool
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m Bool -> ReaderT e m Bool)
-> (a -> m Bool) -> a -> ReaderT e m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> a -> m Bool
forall a. MVar a -> a -> m Bool
forall (m :: * -> *) a. MonadMVar m => MVar a -> a -> m Bool
tryPutMVar' MVar a
x1
  {-# INLINEABLE tryPutMVar' #-}
  isEmptyMVar :: forall a. MVar a -> ReaderT e m Bool
isEmptyMVar = m Bool -> ReaderT e m Bool
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m Bool -> ReaderT e m Bool)
-> (MVar a -> m Bool) -> MVar a -> ReaderT e m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> m Bool
forall a. MVar a -> m Bool
forall (m :: * -> *) a. MonadMVar m => MVar a -> m Bool
isEmptyMVar
  {-# INLINEABLE isEmptyMVar #-}
  withMVar :: forall a b. MVar a -> (a -> ReaderT e m b) -> ReaderT e m b
withMVar = ((a -> m b) -> m b) -> (a -> ReaderT e m b) -> ReaderT e m b
forall (m :: * -> *) a b c e.
Monad m =>
((a -> m b) -> m c) -> (a -> ReaderT e m b) -> ReaderT e m c
runInReader (((a -> m b) -> m b) -> (a -> ReaderT e m b) -> ReaderT e m b)
-> (MVar a -> (a -> m b) -> m b)
-> MVar a
-> (a -> ReaderT e m b)
-> ReaderT e m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> (a -> m b) -> m b
forall a b. MVar a -> (a -> m b) -> m b
forall (m :: * -> *) a b.
MonadMVar m =>
MVar a -> (a -> m b) -> m b
withMVar
  {-# INLINEABLE withMVar #-}
  withMVar' :: forall a b. MVar a -> (a -> ReaderT e m b) -> ReaderT e m b
withMVar' = ((a -> m b) -> m b) -> (a -> ReaderT e m b) -> ReaderT e m b
forall (m :: * -> *) a b c e.
Monad m =>
((a -> m b) -> m c) -> (a -> ReaderT e m b) -> ReaderT e m c
runInReader (((a -> m b) -> m b) -> (a -> ReaderT e m b) -> ReaderT e m b)
-> (MVar a -> (a -> m b) -> m b)
-> MVar a
-> (a -> ReaderT e m b)
-> ReaderT e m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> (a -> m b) -> m b
forall a b. MVar a -> (a -> m b) -> m b
forall (m :: * -> *) a b.
MonadMVar m =>
MVar a -> (a -> m b) -> m b
withMVar'
  {-# INLINEABLE withMVar' #-}
  withMVarMasked :: forall a b. MVar a -> (a -> ReaderT e m b) -> ReaderT e m b
withMVarMasked = ((a -> m b) -> m b) -> (a -> ReaderT e m b) -> ReaderT e m b
forall (m :: * -> *) a b c e.
Monad m =>
((a -> m b) -> m c) -> (a -> ReaderT e m b) -> ReaderT e m c
runInReader (((a -> m b) -> m b) -> (a -> ReaderT e m b) -> ReaderT e m b)
-> (MVar a -> (a -> m b) -> m b)
-> MVar a
-> (a -> ReaderT e m b)
-> ReaderT e m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> (a -> m b) -> m b
forall a b. MVar a -> (a -> m b) -> m b
forall (m :: * -> *) a b.
MonadMVar m =>
MVar a -> (a -> m b) -> m b
withMVarMasked
  {-# INLINEABLE withMVarMasked #-}
  withMVarMasked' :: forall a b. MVar a -> (a -> ReaderT e m b) -> ReaderT e m b
withMVarMasked' = ((a -> m b) -> m b) -> (a -> ReaderT e m b) -> ReaderT e m b
forall (m :: * -> *) a b c e.
Monad m =>
((a -> m b) -> m c) -> (a -> ReaderT e m b) -> ReaderT e m c
runInReader (((a -> m b) -> m b) -> (a -> ReaderT e m b) -> ReaderT e m b)
-> (MVar a -> (a -> m b) -> m b)
-> MVar a
-> (a -> ReaderT e m b)
-> ReaderT e m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> (a -> m b) -> m b
forall a b. MVar a -> (a -> m b) -> m b
forall (m :: * -> *) a b.
MonadMVar m =>
MVar a -> (a -> m b) -> m b
withMVarMasked'
  {-# INLINEABLE withMVarMasked' #-}
  modifyMVar_ :: forall a. MVar a -> (a -> ReaderT e m a) -> ReaderT e m ()
modifyMVar_ = ((a -> m a) -> m ()) -> (a -> ReaderT e m a) -> ReaderT e m ()
forall (m :: * -> *) a b c e.
Monad m =>
((a -> m b) -> m c) -> (a -> ReaderT e m b) -> ReaderT e m c
runInReader (((a -> m a) -> m ()) -> (a -> ReaderT e m a) -> ReaderT e m ())
-> (MVar a -> (a -> m a) -> m ())
-> MVar a
-> (a -> ReaderT e m a)
-> ReaderT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> (a -> m a) -> m ()
forall a. MVar a -> (a -> m a) -> m ()
forall (m :: * -> *) a. MonadMVar m => MVar a -> (a -> m a) -> m ()
modifyMVar_
  {-# INLINEABLE modifyMVar_ #-}
  modifyMVar_' :: forall a. MVar a -> (a -> ReaderT e m a) -> ReaderT e m ()
modifyMVar_' = ((a -> m a) -> m ()) -> (a -> ReaderT e m a) -> ReaderT e m ()
forall (m :: * -> *) a b c e.
Monad m =>
((a -> m b) -> m c) -> (a -> ReaderT e m b) -> ReaderT e m c
runInReader (((a -> m a) -> m ()) -> (a -> ReaderT e m a) -> ReaderT e m ())
-> (MVar a -> (a -> m a) -> m ())
-> MVar a
-> (a -> ReaderT e m a)
-> ReaderT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> (a -> m a) -> m ()
forall a. MVar a -> (a -> m a) -> m ()
forall (m :: * -> *) a. MonadMVar m => MVar a -> (a -> m a) -> m ()
modifyMVar_'
  {-# INLINEABLE modifyMVar_' #-}
  modifyMVar :: forall a b. MVar a -> (a -> ReaderT e m (a, b)) -> ReaderT e m b
modifyMVar = ((a -> m (a, b)) -> m b)
-> (a -> ReaderT e m (a, b)) -> ReaderT e m b
forall (m :: * -> *) a b c e.
Monad m =>
((a -> m b) -> m c) -> (a -> ReaderT e m b) -> ReaderT e m c
runInReader (((a -> m (a, b)) -> m b)
 -> (a -> ReaderT e m (a, b)) -> ReaderT e m b)
-> (MVar a -> (a -> m (a, b)) -> m b)
-> MVar a
-> (a -> ReaderT e m (a, b))
-> ReaderT e m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> (a -> m (a, b)) -> m b
forall a b. MVar a -> (a -> m (a, b)) -> m b
forall (m :: * -> *) a b.
MonadMVar m =>
MVar a -> (a -> m (a, b)) -> m b
modifyMVar
  {-# INLINEABLE modifyMVar #-}
  modifyMVar' :: forall a b. MVar a -> (a -> ReaderT e m (a, b)) -> ReaderT e m b
modifyMVar' = ((a -> m (a, b)) -> m b)
-> (a -> ReaderT e m (a, b)) -> ReaderT e m b
forall (m :: * -> *) a b c e.
Monad m =>
((a -> m b) -> m c) -> (a -> ReaderT e m b) -> ReaderT e m c
runInReader (((a -> m (a, b)) -> m b)
 -> (a -> ReaderT e m (a, b)) -> ReaderT e m b)
-> (MVar a -> (a -> m (a, b)) -> m b)
-> MVar a
-> (a -> ReaderT e m (a, b))
-> ReaderT e m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> (a -> m (a, b)) -> m b
forall a b. MVar a -> (a -> m (a, b)) -> m b
forall (m :: * -> *) a b.
MonadMVar m =>
MVar a -> (a -> m (a, b)) -> m b
modifyMVar'
  {-# INLINEABLE modifyMVar' #-}
  modifyMVarMasked_ :: forall a. MVar a -> (a -> ReaderT e m a) -> ReaderT e m ()
modifyMVarMasked_ = ((a -> m a) -> m ()) -> (a -> ReaderT e m a) -> ReaderT e m ()
forall (m :: * -> *) a b c e.
Monad m =>
((a -> m b) -> m c) -> (a -> ReaderT e m b) -> ReaderT e m c
runInReader (((a -> m a) -> m ()) -> (a -> ReaderT e m a) -> ReaderT e m ())
-> (MVar a -> (a -> m a) -> m ())
-> MVar a
-> (a -> ReaderT e m a)
-> ReaderT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> (a -> m a) -> m ()
forall a. MVar a -> (a -> m a) -> m ()
forall (m :: * -> *) a. MonadMVar m => MVar a -> (a -> m a) -> m ()
modifyMVarMasked_
  {-# INLINEABLE modifyMVarMasked_ #-}
  modifyMVarMasked_' :: forall a. MVar a -> (a -> ReaderT e m a) -> ReaderT e m ()
modifyMVarMasked_' = ((a -> m a) -> m ()) -> (a -> ReaderT e m a) -> ReaderT e m ()
forall (m :: * -> *) a b c e.
Monad m =>
((a -> m b) -> m c) -> (a -> ReaderT e m b) -> ReaderT e m c
runInReader (((a -> m a) -> m ()) -> (a -> ReaderT e m a) -> ReaderT e m ())
-> (MVar a -> (a -> m a) -> m ())
-> MVar a
-> (a -> ReaderT e m a)
-> ReaderT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> (a -> m a) -> m ()
forall a. MVar a -> (a -> m a) -> m ()
forall (m :: * -> *) a. MonadMVar m => MVar a -> (a -> m a) -> m ()
modifyMVarMasked_'
  {-# INLINEABLE modifyMVarMasked_' #-}
  modifyMVarMasked :: forall a b. MVar a -> (a -> ReaderT e m (a, b)) -> ReaderT e m b
modifyMVarMasked = ((a -> m (a, b)) -> m b)
-> (a -> ReaderT e m (a, b)) -> ReaderT e m b
forall (m :: * -> *) a b c e.
Monad m =>
((a -> m b) -> m c) -> (a -> ReaderT e m b) -> ReaderT e m c
runInReader (((a -> m (a, b)) -> m b)
 -> (a -> ReaderT e m (a, b)) -> ReaderT e m b)
-> (MVar a -> (a -> m (a, b)) -> m b)
-> MVar a
-> (a -> ReaderT e m (a, b))
-> ReaderT e m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> (a -> m (a, b)) -> m b
forall a b. MVar a -> (a -> m (a, b)) -> m b
forall (m :: * -> *) a b.
MonadMVar m =>
MVar a -> (a -> m (a, b)) -> m b
modifyMVarMasked
  {-# INLINEABLE modifyMVarMasked #-}
  modifyMVarMasked' :: forall a b. MVar a -> (a -> ReaderT e m (a, b)) -> ReaderT e m b
modifyMVarMasked' = ((a -> m (a, b)) -> m b)
-> (a -> ReaderT e m (a, b)) -> ReaderT e m b
forall (m :: * -> *) a b c e.
Monad m =>
((a -> m b) -> m c) -> (a -> ReaderT e m b) -> ReaderT e m c
runInReader (((a -> m (a, b)) -> m b)
 -> (a -> ReaderT e m (a, b)) -> ReaderT e m b)
-> (MVar a -> (a -> m (a, b)) -> m b)
-> MVar a
-> (a -> ReaderT e m (a, b))
-> ReaderT e m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> (a -> m (a, b)) -> m b
forall a b. MVar a -> (a -> m (a, b)) -> m b
forall (m :: * -> *) a b.
MonadMVar m =>
MVar a -> (a -> m (a, b)) -> m b
modifyMVarMasked'
  {-# INLINEABLE modifyMVarMasked' #-}
  tryReadMVar :: forall a. MVar a -> ReaderT e m (Maybe a)
tryReadMVar = m (Maybe a) -> ReaderT e m (Maybe a)
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe a) -> ReaderT e m (Maybe a))
-> (MVar a -> m (Maybe a)) -> MVar a -> ReaderT e m (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> m (Maybe a)
forall a. MVar a -> m (Maybe a)
forall (m :: * -> *) a. MonadMVar m => MVar a -> m (Maybe a)
tryReadMVar
  {-# INLINEABLE tryReadMVar #-}
  tryReadMVar' :: forall a. MVar a -> ReaderT e m (Maybe a)
tryReadMVar' = m (Maybe a) -> ReaderT e m (Maybe a)
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe a) -> ReaderT e m (Maybe a))
-> (MVar a -> m (Maybe a)) -> MVar a -> ReaderT e m (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> m (Maybe a)
forall a. MVar a -> m (Maybe a)
forall (m :: * -> *) a. MonadMVar m => MVar a -> m (Maybe a)
tryReadMVar'
  {-# INLINEABLE tryReadMVar' #-}
  mkWeakMVar :: forall a. MVar a -> ReaderT e m () -> ReaderT e m (Weak (MVar a))
mkWeakMVar MVar a
var = ((() -> m ()) -> m (Weak (MVar a)))
-> (() -> ReaderT e m ()) -> ReaderT e m (Weak (MVar a))
forall (m :: * -> *) a b c e.
Monad m =>
((a -> m b) -> m c) -> (a -> ReaderT e m b) -> ReaderT e m c
runInReader (\() -> m ()
g -> MVar a -> m () -> m (Weak (MVar a))
forall a. MVar a -> m () -> m (Weak (MVar a))
forall (m :: * -> *) a.
MonadMVar m =>
MVar a -> m () -> m (Weak (MVar a))
mkWeakMVar MVar a
var (() -> m ()
g ())) ((() -> ReaderT e m ()) -> ReaderT e m (Weak (MVar a)))
-> (ReaderT e m () -> () -> ReaderT e m ())
-> ReaderT e m ()
-> ReaderT e m (Weak (MVar a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReaderT e m () -> () -> ReaderT e m ()
forall a b. a -> b -> a
const
  {-# INLINEABLE mkWeakMVar #-}

-- Morally @lift $ f $ \x -> unlift (g x)@.
runInReader :: (Monad m) => ((a -> m b) -> m c) -> (a -> ReaderT e m b) -> ReaderT e m c
runInReader :: forall (m :: * -> *) a b c e.
Monad m =>
((a -> m b) -> m c) -> (a -> ReaderT e m b) -> ReaderT e m c
runInReader (a -> m b) -> m c
f a -> ReaderT e m b
g = ReaderT e m e
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask ReaderT e m e -> (e -> ReaderT e m c) -> ReaderT e m c
forall a b. ReaderT e m a -> (a -> ReaderT e m b) -> ReaderT e m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \e
e -> m c -> ReaderT e m c
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift ((a -> m b) -> m c
f (\a
x -> ReaderT e m b -> e -> m b
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (a -> ReaderT e m b
g a
x) e
e))

-- | Effect for 'QSem' semaphore.
--
-- @since 0.1
class (Monad m) => MonadQSem m where
  -- | Lifted 'QSem.newQSem'.
  --
  -- @since 0.1
  newQSem :: Int -> m QSem

  -- | Lifted 'QSem.waitQSem'.
  --
  -- @since 0.1
  waitQSem :: QSem -> m ()

  -- | Lifted 'QSem.signalQSem'.
  --
  -- @since 0.1
  signalQSem :: QSem -> m ()

-- | @since 0.1
instance MonadQSem IO where
  newQSem :: Int -> IO QSem
newQSem = Int -> IO QSem
QSem.newQSem
  {-# INLINEABLE newQSem #-}
  waitQSem :: QSem -> IO ()
waitQSem = QSem -> IO ()
QSem.waitQSem
  {-# INLINEABLE waitQSem #-}
  signalQSem :: QSem -> IO ()
signalQSem = QSem -> IO ()
QSem.signalQSem
  {-# INLINEABLE signalQSem #-}

-- | @since 0.1
instance (MonadQSem m) => MonadQSem (ReaderT e m) where
  newQSem :: Int -> ReaderT e m QSem
newQSem = m QSem -> ReaderT e m QSem
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m QSem -> ReaderT e m QSem)
-> (Int -> m QSem) -> Int -> ReaderT e m QSem
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> m QSem
forall (m :: * -> *). MonadQSem m => Int -> m QSem
newQSem
  {-# INLINEABLE newQSem #-}
  waitQSem :: QSem -> ReaderT e m ()
waitQSem = m () -> ReaderT e m ()
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT e m ())
-> (QSem -> m ()) -> QSem -> ReaderT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QSem -> m ()
forall (m :: * -> *). MonadQSem m => QSem -> m ()
waitQSem
  {-# INLINEABLE waitQSem #-}
  signalQSem :: QSem -> ReaderT e m ()
signalQSem = m () -> ReaderT e m ()
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT e m ())
-> (QSem -> m ()) -> QSem -> ReaderT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QSem -> m ()
forall (m :: * -> *). MonadQSem m => QSem -> m ()
signalQSem
  {-# INLINEABLE signalQSem #-}

-- | Effect for 'QSemN' semaphore.
--
-- @since 0.1
class (Monad m) => MonadQSemN m where
  -- | Lifted 'QSemN.newQSemN'.
  --
  -- @since 0.1
  newQSemN :: Int -> m QSemN

  -- | Lifted 'QSemN.waitQSemN'.
  --
  -- @since 0.1
  waitQSemN :: QSemN -> Int -> m ()

  -- | Lifted 'QSemN.signalQSemN'.
  --
  -- @since 0.1
  signalQSemN :: QSemN -> Int -> m ()

-- | @since 0.1
instance MonadQSemN IO where
  newQSemN :: Int -> IO QSemN
newQSemN = Int -> IO QSemN
QSemN.newQSemN
  {-# INLINEABLE newQSemN #-}
  waitQSemN :: QSemN -> Int -> IO ()
waitQSemN = QSemN -> Int -> IO ()
QSemN.waitQSemN
  {-# INLINEABLE waitQSemN #-}
  signalQSemN :: QSemN -> Int -> IO ()
signalQSemN = QSemN -> Int -> IO ()
QSemN.signalQSemN
  {-# INLINEABLE signalQSemN #-}

-- | @since 0.1
instance (MonadQSemN m) => MonadQSemN (ReaderT e m) where
  newQSemN :: Int -> ReaderT e m QSemN
newQSemN = m QSemN -> ReaderT e m QSemN
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m QSemN -> ReaderT e m QSemN)
-> (Int -> m QSemN) -> Int -> ReaderT e m QSemN
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> m QSemN
forall (m :: * -> *). MonadQSemN m => Int -> m QSemN
newQSemN
  {-# INLINEABLE newQSemN #-}
  waitQSemN :: QSemN -> Int -> ReaderT e m ()
waitQSemN QSemN
q = m () -> ReaderT e m ()
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT e m ()) -> (Int -> m ()) -> Int -> ReaderT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QSemN -> Int -> m ()
forall (m :: * -> *). MonadQSemN m => QSemN -> Int -> m ()
waitQSemN QSemN
q
  {-# INLINEABLE waitQSemN #-}
  signalQSemN :: QSemN -> Int -> ReaderT e m ()
signalQSemN QSemN
q = m () -> ReaderT e m ()
forall (m :: * -> *) a. Monad m => m a -> ReaderT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT e m ()) -> (Int -> m ()) -> Int -> ReaderT e m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QSemN -> Int -> m ()
forall (m :: * -> *). MonadQSemN m => QSemN -> Int -> m ()
signalQSemN QSemN
q
  {-# INLINEABLE signalQSemN #-}