{-# LANGUAGE UnicodeSyntax #-}
module Control.Monad.NoContinuation.Resource
( NoContinuationResourceT
, runNoContinuationResourceT
, StupidlyManyResources (..)
)
where
import Control.Monad
import Control.Monad.NoContinuation.Resource.Internal
import Control.Monad.Primitive
import Control.Monad.Reader
import Control.Monad.With
import Data.GeneralAllocate
import Data.IntMap.Strict as IntMap
import Data.Primitive.MutVar
runNoContinuationResourceT ∷ (PrimMonad m, MonadWith m) ⇒ NoContinuationResourceT m a → m a
runNoContinuationResourceT :: forall (m :: * -> *) a.
(PrimMonad m, MonadWith m) =>
NoContinuationResourceT m a -> m a
runNoContinuationResourceT (NoContinuationResourceT ReaderT (MutVar (PrimState m) (NoContinuationReleaseMap m)) m a
r) = do
let cleanup' :: [(a, t -> f ())] -> t -> f ()
cleanup' [] t
_ = forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
cleanup' ((a
_, t -> f ()
rel) : [(a, t -> f ())]
tl) t
res = forall a b. (a, b) -> a
fst forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a b. MonadWith m => m a -> m b -> m (a, b)
generalFinally (t -> f ()
rel t
res) ([(a, t -> f ())] -> t -> f ()
cleanup' [(a, t -> f ())]
tl t
res)
cleanup :: MutVar (PrimState m) (NoContinuationReleaseMap m)
-> GeneralReleaseType (WithException m) a -> m ()
cleanup MutVar (PrimState m) (NoContinuationReleaseMap m)
st GeneralReleaseType (WithException m) a
res = do
IntMap (GeneralReleaseType (WithException m) () -> m ())
actions ← forall (m :: * -> *).
NoContinuationReleaseMap m
-> IntMap (GeneralReleaseType (WithException m) () -> m ())
releaseActions forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar MutVar (PrimState m) (NoContinuationReleaseMap m)
st
forall {f :: * -> *} {a} {t}.
MonadWith f =>
[(a, t -> f ())] -> t -> f ()
cleanup' (forall a. IntMap a -> [(Key, a)]
toAscList IntMap (GeneralReleaseType (WithException m) () -> m ())
actions) (forall (f :: * -> *) a. Functor f => f a -> f ()
void GeneralReleaseType (WithException m) a
res)
alloc :: GeneralAllocate
m
(WithException m)
()
releaseArg
(MutVar (PrimState m) (NoContinuationReleaseMap m))
alloc = forall (m :: * -> *) e releaseReturn releaseArg a.
((forall x. m x -> m x)
-> m (GeneralAllocated m e releaseReturn releaseArg a))
-> GeneralAllocate m e releaseReturn releaseArg a
GeneralAllocate forall a b. (a -> b) -> a -> b
$ \forall x. m x -> m x
restore → do
MutVar (PrimState m) (NoContinuationReleaseMap m)
st ←
forall x. m x -> m x
restore forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a.
PrimMonad m =>
a -> m (MutVar (PrimState m) a)
newMutVar forall a b. (a -> b) -> a -> b
$
NoContinuationReleaseMap
{ nextKey :: Key
nextKey = forall a. Bounded a => a
maxBound
, releaseActions :: IntMap (GeneralReleaseType (WithException m) () -> m ())
releaseActions = forall a. IntMap a
IntMap.empty
}
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) e releaseReturn releaseArg a.
a
-> (GeneralReleaseType e releaseArg -> m releaseReturn)
-> GeneralAllocated m e releaseReturn releaseArg a
GeneralAllocated MutVar (PrimState m) (NoContinuationReleaseMap m)
st (forall {m :: * -> *} {a}.
(PrimMonad m, MonadWith m) =>
MutVar (PrimState m) (NoContinuationReleaseMap m)
-> GeneralReleaseType (WithException m) a -> m ()
cleanup MutVar (PrimState m) (NoContinuationReleaseMap m)
st)
forall (m :: * -> *) b a.
MonadWith m =>
With m b a -> (a -> m b) -> m b
generalWith forall {releaseArg}.
GeneralAllocate
m
(WithException m)
()
releaseArg
(MutVar (PrimState m) (NoContinuationReleaseMap m))
alloc (forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT (MutVar (PrimState m) (NoContinuationReleaseMap m)) m a
r)