{-# LANGUAGE RecordWildCards #-}
module Metro.Lock
  ( Lock
  , new
  , with
  ) where


import           UnliftIO (MVar, MonadIO, MonadUnliftIO, newMVar, withMVar)

newtype Lock = Lock { Lock -> MVar ()
un :: MVar () }

new :: MonadIO m => m Lock
new :: m Lock
new = MVar () -> Lock
Lock (MVar () -> Lock) -> m (MVar ()) -> m Lock
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> () -> m (MVar ())
forall (m :: * -> *) a. MonadIO m => a -> m (MVar a)
newMVar ()

with :: MonadUnliftIO m => Lock -> m a -> m a
with :: Lock -> m a -> m a
with Lock{MVar ()
un :: MVar ()
un :: Lock -> MVar ()
..} = MVar () -> (() -> m a) -> m a
forall (m :: * -> *) a b.
MonadUnliftIO m =>
MVar a -> (a -> m b) -> m b
withMVar MVar ()
un ((() -> m a) -> m a) -> (m a -> () -> m a) -> m a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> () -> m a
forall a b. a -> b -> a
const