{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilyDependencies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE UndecidableSuperClasses #-}
module Graphula.Idempotent
( GraphulaIdempotentT
, runGraphulaIdempotentT
) where
import Prelude
import Control.Monad.IO.Unlift
import Control.Monad.Reader (MonadReader, ReaderT, ask, runReaderT)
import Control.Monad.Trans (MonadTrans, lift)
import Data.Foldable (for_)
import Data.IORef (IORef, modifyIORef', newIORef, readIORef)
import Database.Persist (Entity (..))
import Graphula.Class
import UnliftIO.Exception (SomeException, catch, mask, throwIO)
newtype GraphulaIdempotentT m a = GraphulaIdempotentT
{ forall (m :: * -> *) a.
GraphulaIdempotentT m a -> ReaderT (IORef (m ())) m a
runGraphulaIdempotentT' :: ReaderT (IORef (m ())) m a
}
deriving newtype
( (forall a b.
(a -> b) -> GraphulaIdempotentT m a -> GraphulaIdempotentT m b)
-> (forall a b.
a -> GraphulaIdempotentT m b -> GraphulaIdempotentT m a)
-> Functor (GraphulaIdempotentT m)
forall a b. a -> GraphulaIdempotentT m b -> GraphulaIdempotentT m a
forall a b.
(a -> b) -> GraphulaIdempotentT m a -> GraphulaIdempotentT m b
forall (m :: * -> *) a b.
Functor m =>
a -> GraphulaIdempotentT m b -> GraphulaIdempotentT m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> GraphulaIdempotentT m a -> GraphulaIdempotentT m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> GraphulaIdempotentT m a -> GraphulaIdempotentT m b
fmap :: forall a b.
(a -> b) -> GraphulaIdempotentT m a -> GraphulaIdempotentT m b
$c<$ :: forall (m :: * -> *) a b.
Functor m =>
a -> GraphulaIdempotentT m b -> GraphulaIdempotentT m a
<$ :: forall a b. a -> GraphulaIdempotentT m b -> GraphulaIdempotentT m a
Functor
, Functor (GraphulaIdempotentT m)
Functor (GraphulaIdempotentT m) =>
(forall a. a -> GraphulaIdempotentT m a)
-> (forall a b.
GraphulaIdempotentT m (a -> b)
-> GraphulaIdempotentT m a -> GraphulaIdempotentT m b)
-> (forall a b c.
(a -> b -> c)
-> GraphulaIdempotentT m a
-> GraphulaIdempotentT m b
-> GraphulaIdempotentT m c)
-> (forall a b.
GraphulaIdempotentT m a
-> GraphulaIdempotentT m b -> GraphulaIdempotentT m b)
-> (forall a b.
GraphulaIdempotentT m a
-> GraphulaIdempotentT m b -> GraphulaIdempotentT m a)
-> Applicative (GraphulaIdempotentT m)
forall a. a -> GraphulaIdempotentT m a
forall a b.
GraphulaIdempotentT m a
-> GraphulaIdempotentT m b -> GraphulaIdempotentT m a
forall a b.
GraphulaIdempotentT m a
-> GraphulaIdempotentT m b -> GraphulaIdempotentT m b
forall a b.
GraphulaIdempotentT m (a -> b)
-> GraphulaIdempotentT m a -> GraphulaIdempotentT m b
forall a b c.
(a -> b -> c)
-> GraphulaIdempotentT m a
-> GraphulaIdempotentT m b
-> GraphulaIdempotentT m c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
forall (m :: * -> *).
Applicative m =>
Functor (GraphulaIdempotentT m)
forall (m :: * -> *) a.
Applicative m =>
a -> GraphulaIdempotentT m a
forall (m :: * -> *) a b.
Applicative m =>
GraphulaIdempotentT m a
-> GraphulaIdempotentT m b -> GraphulaIdempotentT m a
forall (m :: * -> *) a b.
Applicative m =>
GraphulaIdempotentT m a
-> GraphulaIdempotentT m b -> GraphulaIdempotentT m b
forall (m :: * -> *) a b.
Applicative m =>
GraphulaIdempotentT m (a -> b)
-> GraphulaIdempotentT m a -> GraphulaIdempotentT m b
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> GraphulaIdempotentT m a
-> GraphulaIdempotentT m b
-> GraphulaIdempotentT m c
$cpure :: forall (m :: * -> *) a.
Applicative m =>
a -> GraphulaIdempotentT m a
pure :: forall a. a -> GraphulaIdempotentT m a
$c<*> :: forall (m :: * -> *) a b.
Applicative m =>
GraphulaIdempotentT m (a -> b)
-> GraphulaIdempotentT m a -> GraphulaIdempotentT m b
<*> :: forall a b.
GraphulaIdempotentT m (a -> b)
-> GraphulaIdempotentT m a -> GraphulaIdempotentT m b
$cliftA2 :: forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> GraphulaIdempotentT m a
-> GraphulaIdempotentT m b
-> GraphulaIdempotentT m c
liftA2 :: forall a b c.
(a -> b -> c)
-> GraphulaIdempotentT m a
-> GraphulaIdempotentT m b
-> GraphulaIdempotentT m c
$c*> :: forall (m :: * -> *) a b.
Applicative m =>
GraphulaIdempotentT m a
-> GraphulaIdempotentT m b -> GraphulaIdempotentT m b
*> :: forall a b.
GraphulaIdempotentT m a
-> GraphulaIdempotentT m b -> GraphulaIdempotentT m b
$c<* :: forall (m :: * -> *) a b.
Applicative m =>
GraphulaIdempotentT m a
-> GraphulaIdempotentT m b -> GraphulaIdempotentT m a
<* :: forall a b.
GraphulaIdempotentT m a
-> GraphulaIdempotentT m b -> GraphulaIdempotentT m a
Applicative
, Applicative (GraphulaIdempotentT m)
Applicative (GraphulaIdempotentT m) =>
(forall a b.
GraphulaIdempotentT m a
-> (a -> GraphulaIdempotentT m b) -> GraphulaIdempotentT m b)
-> (forall a b.
GraphulaIdempotentT m a
-> GraphulaIdempotentT m b -> GraphulaIdempotentT m b)
-> (forall a. a -> GraphulaIdempotentT m a)
-> Monad (GraphulaIdempotentT m)
forall a. a -> GraphulaIdempotentT m a
forall a b.
GraphulaIdempotentT m a
-> GraphulaIdempotentT m b -> GraphulaIdempotentT m b
forall a b.
GraphulaIdempotentT m a
-> (a -> GraphulaIdempotentT m b) -> GraphulaIdempotentT m b
forall (m :: * -> *).
Monad m =>
Applicative (GraphulaIdempotentT m)
forall (m :: * -> *) a. Monad m => a -> GraphulaIdempotentT m a
forall (m :: * -> *) a b.
Monad m =>
GraphulaIdempotentT m a
-> GraphulaIdempotentT m b -> GraphulaIdempotentT m b
forall (m :: * -> *) a b.
Monad m =>
GraphulaIdempotentT m a
-> (a -> GraphulaIdempotentT m b) -> GraphulaIdempotentT m b
forall (m :: * -> *).
Applicative m =>
(forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
GraphulaIdempotentT m a
-> (a -> GraphulaIdempotentT m b) -> GraphulaIdempotentT m b
>>= :: forall a b.
GraphulaIdempotentT m a
-> (a -> GraphulaIdempotentT m b) -> GraphulaIdempotentT m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
GraphulaIdempotentT m a
-> GraphulaIdempotentT m b -> GraphulaIdempotentT m b
>> :: forall a b.
GraphulaIdempotentT m a
-> GraphulaIdempotentT m b -> GraphulaIdempotentT m b
$creturn :: forall (m :: * -> *) a. Monad m => a -> GraphulaIdempotentT m a
return :: forall a. a -> GraphulaIdempotentT m a
Monad
, Monad (GraphulaIdempotentT m)
Monad (GraphulaIdempotentT m) =>
(forall a. IO a -> GraphulaIdempotentT m a)
-> MonadIO (GraphulaIdempotentT m)
forall a. IO a -> GraphulaIdempotentT m a
forall (m :: * -> *).
Monad m =>
(forall a. IO a -> m a) -> MonadIO m
forall (m :: * -> *). MonadIO m => Monad (GraphulaIdempotentT m)
forall (m :: * -> *) a.
MonadIO m =>
IO a -> GraphulaIdempotentT m a
$cliftIO :: forall (m :: * -> *) a.
MonadIO m =>
IO a -> GraphulaIdempotentT m a
liftIO :: forall a. IO a -> GraphulaIdempotentT m a
MonadIO
, MonadReader (IORef (m ()))
)
instance MonadUnliftIO m => MonadUnliftIO (GraphulaIdempotentT m) where
{-# INLINE withRunInIO #-}
withRunInIO :: forall b.
((forall a. GraphulaIdempotentT m a -> IO a) -> IO b)
-> GraphulaIdempotentT m b
withRunInIO (forall a. GraphulaIdempotentT m a -> IO a) -> IO b
inner = ReaderT (IORef (m ())) m b -> GraphulaIdempotentT m b
forall (m :: * -> *) a.
ReaderT (IORef (m ())) m a -> GraphulaIdempotentT m a
GraphulaIdempotentT (ReaderT (IORef (m ())) m b -> GraphulaIdempotentT m b)
-> ReaderT (IORef (m ())) m b -> GraphulaIdempotentT m b
forall a b. (a -> b) -> a -> b
$ ((forall a. ReaderT (IORef (m ())) m a -> IO a) -> IO b)
-> ReaderT (IORef (m ())) m b
forall b.
((forall a. ReaderT (IORef (m ())) m a -> IO a) -> IO b)
-> ReaderT (IORef (m ())) m b
forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO (((forall a. ReaderT (IORef (m ())) m a -> IO a) -> IO b)
-> ReaderT (IORef (m ())) m b)
-> ((forall a. ReaderT (IORef (m ())) m a -> IO a) -> IO b)
-> ReaderT (IORef (m ())) m b
forall a b. (a -> b) -> a -> b
$ \forall a. ReaderT (IORef (m ())) m a -> IO a
run ->
(forall a. GraphulaIdempotentT m a -> IO a) -> IO b
inner ((forall a. GraphulaIdempotentT m a -> IO a) -> IO b)
-> (forall a. GraphulaIdempotentT m a -> IO a) -> IO b
forall a b. (a -> b) -> a -> b
$ ReaderT (IORef (m ())) m a -> IO a
forall a. ReaderT (IORef (m ())) m a -> IO a
run (ReaderT (IORef (m ())) m a -> IO a)
-> (GraphulaIdempotentT m a -> ReaderT (IORef (m ())) m a)
-> GraphulaIdempotentT m a
-> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GraphulaIdempotentT m a -> ReaderT (IORef (m ())) m a
forall (m :: * -> *) a.
GraphulaIdempotentT m a -> ReaderT (IORef (m ())) m a
runGraphulaIdempotentT'
instance MonadTrans GraphulaIdempotentT where
lift :: forall (m :: * -> *) a. Monad m => m a -> GraphulaIdempotentT m a
lift = ReaderT (IORef (m ())) m a -> GraphulaIdempotentT m a
forall (m :: * -> *) a.
ReaderT (IORef (m ())) m a -> GraphulaIdempotentT m a
GraphulaIdempotentT (ReaderT (IORef (m ())) m a -> GraphulaIdempotentT m a)
-> (m a -> ReaderT (IORef (m ())) m a)
-> m a
-> GraphulaIdempotentT m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> ReaderT (IORef (m ())) m a
forall (m :: * -> *) a.
Monad m =>
m a -> ReaderT (IORef (m ())) m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift
instance
(MonadIO m, MonadGraphulaFrontend m)
=> MonadGraphulaFrontend (GraphulaIdempotentT m)
where
insert :: forall a.
(PersistEntityBackend a ~ SqlBackend, PersistEntity a,
Monad (GraphulaIdempotentT m), GraphulaSafeToInsert a) =>
Maybe (Key a) -> a -> GraphulaIdempotentT m (Maybe (Entity a))
insert Maybe (Key a)
mKey a
n = do
IORef (m ())
finalizersRef <- GraphulaIdempotentT m (IORef (m ()))
forall r (m :: * -> *). MonadReader r m => m r
ask
Maybe (Entity a)
mEnt <- m (Maybe (Entity a)) -> GraphulaIdempotentT m (Maybe (Entity a))
forall (m :: * -> *) a. Monad m => m a -> GraphulaIdempotentT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe (Entity a)) -> GraphulaIdempotentT m (Maybe (Entity a)))
-> m (Maybe (Entity a)) -> GraphulaIdempotentT m (Maybe (Entity a))
forall a b. (a -> b) -> a -> b
$ Maybe (Key a) -> a -> m (Maybe (Entity a))
forall a.
(PersistEntityBackend a ~ SqlBackend, PersistEntity a, Monad m,
GraphulaSafeToInsert a) =>
Maybe (Key a) -> a -> m (Maybe (Entity a))
forall (m :: * -> *) a.
(MonadGraphulaFrontend m, PersistEntityBackend a ~ SqlBackend,
PersistEntity a, Monad m, GraphulaSafeToInsert a) =>
Maybe (Key a) -> a -> m (Maybe (Entity a))
insert Maybe (Key a)
mKey a
n
Maybe (Key a)
-> (Key a -> GraphulaIdempotentT m ()) -> GraphulaIdempotentT m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ (Entity a -> Key a
forall record. Entity record -> Key record
entityKey (Entity a -> Key a) -> Maybe (Entity a) -> Maybe (Key a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (Entity a)
mEnt) ((Key a -> GraphulaIdempotentT m ()) -> GraphulaIdempotentT m ())
-> (Key a -> GraphulaIdempotentT m ()) -> GraphulaIdempotentT m ()
forall a b. (a -> b) -> a -> b
$
\Key a
key -> IO () -> GraphulaIdempotentT m ()
forall a. IO a -> GraphulaIdempotentT m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> GraphulaIdempotentT m ())
-> IO () -> GraphulaIdempotentT m ()
forall a b. (a -> b) -> a -> b
$ IORef (m ()) -> (m () -> m ()) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' IORef (m ())
finalizersRef (Key a -> m ()
forall a.
(PersistEntityBackend a ~ SqlBackend, PersistEntity a, Monad m) =>
Key a -> m ()
forall (m :: * -> *) a.
(MonadGraphulaFrontend m, PersistEntityBackend a ~ SqlBackend,
PersistEntity a, Monad m) =>
Key a -> m ()
remove Key a
key m () -> m () -> m ()
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>)
Maybe (Entity a) -> GraphulaIdempotentT m (Maybe (Entity a))
forall a. a -> GraphulaIdempotentT m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (Entity a)
mEnt
insertKeyed :: forall a.
(PersistEntityBackend a ~ SqlBackend, PersistEntity a,
Monad (GraphulaIdempotentT m)) =>
Key a -> a -> GraphulaIdempotentT m (Maybe (Entity a))
insertKeyed Key a
key a
n = do
IORef (m ())
finalizersRef <- GraphulaIdempotentT m (IORef (m ()))
forall r (m :: * -> *). MonadReader r m => m r
ask
Maybe (Entity a)
mEnt <- m (Maybe (Entity a)) -> GraphulaIdempotentT m (Maybe (Entity a))
forall (m :: * -> *) a. Monad m => m a -> GraphulaIdempotentT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Maybe (Entity a)) -> GraphulaIdempotentT m (Maybe (Entity a)))
-> m (Maybe (Entity a)) -> GraphulaIdempotentT m (Maybe (Entity a))
forall a b. (a -> b) -> a -> b
$ Key a -> a -> m (Maybe (Entity a))
forall a.
(PersistEntityBackend a ~ SqlBackend, PersistEntity a, Monad m) =>
Key a -> a -> m (Maybe (Entity a))
forall (m :: * -> *) a.
(MonadGraphulaFrontend m, PersistEntityBackend a ~ SqlBackend,
PersistEntity a, Monad m) =>
Key a -> a -> m (Maybe (Entity a))
insertKeyed Key a
key a
n
Maybe (Key a)
-> (Key a -> GraphulaIdempotentT m ()) -> GraphulaIdempotentT m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ (Entity a -> Key a
forall record. Entity record -> Key record
entityKey (Entity a -> Key a) -> Maybe (Entity a) -> Maybe (Key a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (Entity a)
mEnt) ((Key a -> GraphulaIdempotentT m ()) -> GraphulaIdempotentT m ())
-> (Key a -> GraphulaIdempotentT m ()) -> GraphulaIdempotentT m ()
forall a b. (a -> b) -> a -> b
$
\Key a
key' -> IO () -> GraphulaIdempotentT m ()
forall a. IO a -> GraphulaIdempotentT m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> GraphulaIdempotentT m ())
-> IO () -> GraphulaIdempotentT m ()
forall a b. (a -> b) -> a -> b
$ IORef (m ()) -> (m () -> m ()) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' IORef (m ())
finalizersRef (Key a -> m ()
forall a.
(PersistEntityBackend a ~ SqlBackend, PersistEntity a, Monad m) =>
Key a -> m ()
forall (m :: * -> *) a.
(MonadGraphulaFrontend m, PersistEntityBackend a ~ SqlBackend,
PersistEntity a, Monad m) =>
Key a -> m ()
remove Key a
key' m () -> m () -> m ()
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>)
Maybe (Entity a) -> GraphulaIdempotentT m (Maybe (Entity a))
forall a. a -> GraphulaIdempotentT m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (Entity a)
mEnt
remove :: forall a.
(PersistEntityBackend a ~ SqlBackend, PersistEntity a,
Monad (GraphulaIdempotentT m)) =>
Key a -> GraphulaIdempotentT m ()
remove = m () -> GraphulaIdempotentT m ()
forall (m :: * -> *) a. Monad m => m a -> GraphulaIdempotentT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> GraphulaIdempotentT m ())
-> (Key a -> m ()) -> Key a -> GraphulaIdempotentT m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key a -> m ()
forall a.
(PersistEntityBackend a ~ SqlBackend, PersistEntity a, Monad m) =>
Key a -> m ()
forall (m :: * -> *) a.
(MonadGraphulaFrontend m, PersistEntityBackend a ~ SqlBackend,
PersistEntity a, Monad m) =>
Key a -> m ()
remove
runGraphulaIdempotentT :: MonadUnliftIO m => GraphulaIdempotentT m a -> m a
runGraphulaIdempotentT :: forall (m :: * -> *) a.
MonadUnliftIO m =>
GraphulaIdempotentT m a -> m a
runGraphulaIdempotentT GraphulaIdempotentT m a
action = ((forall a. m a -> m a) -> m a) -> m a
forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> m a) -> m b) -> m b
mask (((forall a. m a -> m a) -> m a) -> m a)
-> ((forall a. m a -> m a) -> m a) -> m a
forall a b. (a -> b) -> a -> b
$ \forall a. m a -> m a
unmasked -> do
IORef (m ())
finalizersRef <- IO (IORef (m ())) -> m (IORef (m ()))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef (m ())) -> m (IORef (m ())))
-> (m () -> IO (IORef (m ()))) -> m () -> m (IORef (m ()))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m () -> IO (IORef (m ()))
forall a. a -> IO (IORef a)
newIORef (m () -> m (IORef (m ()))) -> m () -> m (IORef (m ()))
forall a b. (a -> b) -> a -> b
$ () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
a
x <-
m a -> m a
forall a. m a -> m a
unmasked (m a -> m a) -> m a -> m a
forall a b. (a -> b) -> a -> b
$
ReaderT (IORef (m ())) m a -> IORef (m ()) -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (GraphulaIdempotentT m a -> ReaderT (IORef (m ())) m a
forall (m :: * -> *) a.
GraphulaIdempotentT m a -> ReaderT (IORef (m ())) m a
runGraphulaIdempotentT' GraphulaIdempotentT m a
action) IORef (m ())
finalizersRef
m a -> (SomeException -> m a) -> m a
forall (m :: * -> *) e a.
(MonadUnliftIO m, Exception e) =>
m a -> (e -> m a) -> m a
`catch` IORef (m ()) -> SomeException -> m a
forall (m :: * -> *) a b.
MonadIO m =>
IORef (m a) -> SomeException -> m b
rollbackRethrow IORef (m ())
finalizersRef
IORef (m ()) -> m a -> m a
forall (m :: * -> *) a b. MonadIO m => IORef (m a) -> m b -> m b
rollback IORef (m ())
finalizersRef (m a -> m a) -> m a -> m a
forall a b. (a -> b) -> a -> b
$ a -> m a
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
x
where
rollback :: MonadIO m => IORef (m a) -> m b -> m b
rollback :: forall (m :: * -> *) a b. MonadIO m => IORef (m a) -> m b -> m b
rollback IORef (m a)
finalizersRef m b
x = do
m a
finalizers <- IO (m a) -> m (m a)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (m a) -> m (m a)) -> IO (m a) -> m (m a)
forall a b. (a -> b) -> a -> b
$ IORef (m a) -> IO (m a)
forall a. IORef a -> IO a
readIORef IORef (m a)
finalizersRef
m a
finalizers m a -> m b -> m b
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> m b
x
rollbackRethrow :: MonadIO m => IORef (m a) -> SomeException -> m b
rollbackRethrow :: forall (m :: * -> *) a b.
MonadIO m =>
IORef (m a) -> SomeException -> m b
rollbackRethrow IORef (m a)
finalizersRef (SomeException
e :: SomeException) =
IORef (m a) -> m b -> m b
forall (m :: * -> *) a b. MonadIO m => IORef (m a) -> m b -> m b
rollback IORef (m a)
finalizersRef (SomeException -> m b
forall (m :: * -> *) e a. (MonadIO m, Exception e) => e -> m a
throwIO SomeException
e)