module MonadVar.Instances.MVar where

import           MonadVar.Prelude
import           MonadVar.Classes
import           MonadVar.Default
import           Control.Concurrent.MVar

instance MonadIO m => MonadNew   m MVar where
  new :: a -> m (MVar a)
new = IO (MVar a) -> m (MVar a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (MVar a) -> m (MVar a))
-> (a -> IO (MVar a)) -> a -> m (MVar a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> IO (MVar a)
forall a. a -> IO (MVar a)
newMVar
  {-# INLINE new #-}

instance MonadIO m => MonadLock  m MVar where
  hold :: MVar a -> m a
hold     = IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> m a) -> (MVar a -> IO a) -> MVar a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> IO a
forall a. MVar a -> IO a
takeMVar
  {-# INLINE hold #-}

  fill :: MVar a -> a -> m ()
fill     = IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> (MVar a -> a -> IO ()) -> MVar a -> a -> m ()
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
.* MVar a -> a -> IO ()
forall a. MVar a -> a -> IO ()
putMVar
  {-# INLINE fill #-}

  tryHold :: MVar a -> m (Maybe a)
tryHold  = IO (Maybe a) -> m (Maybe a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe a) -> m (Maybe a))
-> (MVar a -> IO (Maybe a)) -> MVar a -> m (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> IO (Maybe a)
forall a. MVar a -> IO (Maybe a)
tryTakeMVar
  {-# INLINE tryHold #-}

  tryFill :: MVar a -> a -> m Bool
tryFill  = IO Bool -> m Bool
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> m Bool)
-> (MVar a -> a -> IO Bool) -> MVar a -> a -> m Bool
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
.* MVar a -> a -> IO Bool
forall a. MVar a -> a -> IO Bool
tryPutMVar
  {-# INLINE tryFill #-}

  tryRead :: MVar a -> m (Maybe a)
tryRead  = IO (Maybe a) -> m (Maybe a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe a) -> m (Maybe a))
-> (MVar a -> IO (Maybe a)) -> MVar a -> m (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> IO (Maybe a)
forall a. MVar a -> IO (Maybe a)
tryReadMVar
  {-# INLINE tryRead #-}

  newEmpty :: m (MVar a)
newEmpty = IO (MVar a) -> m (MVar a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO (MVar a)
forall a. IO (MVar a)
newEmptyMVar
  {-# INLINE newEmpty #-}

  isEmpty :: MVar a -> m Bool
isEmpty  = IO Bool -> m Bool
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> m Bool) -> (MVar a -> IO Bool) -> MVar a -> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> IO Bool
forall a. MVar a -> IO Bool
isEmptyMVar
  {-# INLINE isEmpty #-}

instance MonadIO m => MonadRead  m MVar where
  read :: MVar a -> m a
read = IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> m a) -> (MVar a -> IO a) -> MVar a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> IO a
forall a. MVar a -> IO a
readMVar
  {-# INLINE read #-}

instance MonadIO m => MonadWrite m MVar where
  write :: MVar a -> a -> m ()
write = IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> (MVar a -> a -> IO ()) -> MVar a -> a -> m ()
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
.* IO () -> IO ()
forall a. IO a -> IO a
mask_ (IO () -> IO ()) -> (MVar a -> a -> IO ()) -> MVar a -> a -> IO ()
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
.* MVar a -> a -> IO ()
forall (m :: * -> *) (v :: * -> *) a.
MonadLock m v =>
v a -> a -> m ()
defaultLockUnsafeWrite
  {-# INLINE write #-}

instance MonadIO m => MonadSwap  m MVar where
  swap :: MVar a -> a -> m a
swap = IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> m a) -> (MVar a -> a -> IO a) -> MVar a -> a -> m a
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
.* IO a -> IO a
forall a. IO a -> IO a
mask_ (IO a -> IO a) -> (MVar a -> a -> IO a) -> MVar a -> a -> IO a
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
.* MVar a -> a -> IO a
forall (m :: * -> *) (v :: * -> *) a.
MonadLock m v =>
v a -> a -> m a
defaultLockUnsafeSwap
  {-# INLINE swap #-}

instance MonadIO m => MonadMutate_ m MVar where
  mutate_ :: MVar a -> (a -> a) -> m ()
mutate_ MVar a
v a -> a
f = IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> ((a -> IO a) -> IO ()) -> (a -> IO a) -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> (a -> IO a) -> IO ()
forall (f :: * -> *) (m :: * -> *) (v :: * -> *) a.
MonadMutateM_ f m v =>
v a -> (a -> f a) -> m ()
mutateM_ MVar a
v ((a -> IO a) -> m ()) -> (a -> IO a) -> m ()
forall a b. (a -> b) -> a -> b
$ a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> IO a) -> (a -> a) -> a -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f
  {-# INLINE mutate_ #-}

instance MonadIO m => MonadMutate  m MVar where
  mutate :: MVar a -> (a -> (a, b)) -> m b
mutate MVar a
v a -> (a, b)
f = IO b -> m b
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO b -> m b)
-> ((a -> IO (a, b)) -> IO b) -> (a -> IO (a, b)) -> m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar a -> (a -> IO (a, b)) -> IO b
forall (f :: * -> *) (m :: * -> *) (v :: * -> *) a b.
MonadMutateM f m v =>
v a -> (a -> f (a, b)) -> m b
mutateM MVar a
v ((a -> IO (a, b)) -> m b) -> (a -> IO (a, b)) -> m b
forall a b. (a -> b) -> a -> b
$ (a, b) -> IO (a, b)
forall (m :: * -> *) a. Monad m => a -> m a
return ((a, b) -> IO (a, b)) -> (a -> (a, b)) -> a -> IO (a, b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (a, b)
f
  {-# INLINE mutate #-}

instance IO ~ io => MonadMutateM_ io IO MVar where
  mutateM_ :: MVar a -> (a -> io a) -> IO ()
mutateM_ = MVar a -> (a -> io a) -> IO ()
forall (v :: * -> *) a.
MonadLock IO v =>
v a -> (a -> IO a) -> IO ()
defaultLockIOMutateM_
  {-# INLINE mutateM_ #-}

instance IO ~ io => MonadMutateM  io IO MVar where
  mutateM :: MVar a -> (a -> io (a, b)) -> IO b
mutateM = MVar a -> (a -> io (a, b)) -> IO b
forall (v :: * -> *) a b.
MonadLock IO v =>
v a -> (a -> IO (a, b)) -> IO b
defaultLockIOMutateM
  {-# INLINE mutateM #-}