{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE UnicodeSyntax #-}
module Control.Monad.NoContinuation.Resource.Internal where
import Control.Applicative
import Control.Exception.Safe
import Control.Monad
import Control.Monad.Allocate
import Control.Monad.Fix
import Control.Monad.Primitive
import Control.Monad.Reader
import Control.Monad.State.Lazy
import Control.Monad.With
import Control.Monad.Writer.Lazy
import Data.GeneralAllocate
import Data.IntMap.Strict as IntMap
import Data.Primitive.MutVar
newtype NoContinuationResourceT m a = NoContinuationResourceT {forall (m :: * -> *) a.
NoContinuationResourceT m a
-> ReaderT (MutVar (PrimState m) (NoContinuationReleaseMap m)) m a
unNoContinuationResourceT ∷ ReaderT (MutVar (PrimState m) (NoContinuationReleaseMap m)) m a}
deriving newtype (forall a. a -> NoContinuationResourceT m a
forall a b.
NoContinuationResourceT m a
-> NoContinuationResourceT m b -> NoContinuationResourceT m a
forall a b.
NoContinuationResourceT m a
-> NoContinuationResourceT m b -> NoContinuationResourceT m b
forall a b.
NoContinuationResourceT m (a -> b)
-> NoContinuationResourceT m a -> NoContinuationResourceT m b
forall a b c.
(a -> b -> c)
-> NoContinuationResourceT m a
-> NoContinuationResourceT m b
-> NoContinuationResourceT 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 (NoContinuationResourceT m)
forall (m :: * -> *) a.
Applicative m =>
a -> NoContinuationResourceT m a
forall (m :: * -> *) a b.
Applicative m =>
NoContinuationResourceT m a
-> NoContinuationResourceT m b -> NoContinuationResourceT m a
forall (m :: * -> *) a b.
Applicative m =>
NoContinuationResourceT m a
-> NoContinuationResourceT m b -> NoContinuationResourceT m b
forall (m :: * -> *) a b.
Applicative m =>
NoContinuationResourceT m (a -> b)
-> NoContinuationResourceT m a -> NoContinuationResourceT m b
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> NoContinuationResourceT m a
-> NoContinuationResourceT m b
-> NoContinuationResourceT m c
<* :: forall a b.
NoContinuationResourceT m a
-> NoContinuationResourceT m b -> NoContinuationResourceT m a
$c<* :: forall (m :: * -> *) a b.
Applicative m =>
NoContinuationResourceT m a
-> NoContinuationResourceT m b -> NoContinuationResourceT m a
*> :: forall a b.
NoContinuationResourceT m a
-> NoContinuationResourceT m b -> NoContinuationResourceT m b
$c*> :: forall (m :: * -> *) a b.
Applicative m =>
NoContinuationResourceT m a
-> NoContinuationResourceT m b -> NoContinuationResourceT m b
liftA2 :: forall a b c.
(a -> b -> c)
-> NoContinuationResourceT m a
-> NoContinuationResourceT m b
-> NoContinuationResourceT m c
$cliftA2 :: forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> NoContinuationResourceT m a
-> NoContinuationResourceT m b
-> NoContinuationResourceT m c
<*> :: forall a b.
NoContinuationResourceT m (a -> b)
-> NoContinuationResourceT m a -> NoContinuationResourceT m b
$c<*> :: forall (m :: * -> *) a b.
Applicative m =>
NoContinuationResourceT m (a -> b)
-> NoContinuationResourceT m a -> NoContinuationResourceT m b
pure :: forall a. a -> NoContinuationResourceT m a
$cpure :: forall (m :: * -> *) a.
Applicative m =>
a -> NoContinuationResourceT m a
Applicative, forall a b.
a -> NoContinuationResourceT m b -> NoContinuationResourceT m a
forall a b.
(a -> b)
-> NoContinuationResourceT m a -> NoContinuationResourceT m b
forall (m :: * -> *) a b.
Functor m =>
a -> NoContinuationResourceT m b -> NoContinuationResourceT m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b)
-> NoContinuationResourceT m a -> NoContinuationResourceT m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b.
a -> NoContinuationResourceT m b -> NoContinuationResourceT m a
$c<$ :: forall (m :: * -> *) a b.
Functor m =>
a -> NoContinuationResourceT m b -> NoContinuationResourceT m a
fmap :: forall a b.
(a -> b)
-> NoContinuationResourceT m a -> NoContinuationResourceT m b
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b)
-> NoContinuationResourceT m a -> NoContinuationResourceT m b
Functor, forall a. a -> NoContinuationResourceT m a
forall a b.
NoContinuationResourceT m a
-> NoContinuationResourceT m b -> NoContinuationResourceT m b
forall a b.
NoContinuationResourceT m a
-> (a -> NoContinuationResourceT m b)
-> NoContinuationResourceT m b
forall {m :: * -> *}.
Monad m =>
Applicative (NoContinuationResourceT m)
forall (m :: * -> *) a. Monad m => a -> NoContinuationResourceT m a
forall (m :: * -> *) a b.
Monad m =>
NoContinuationResourceT m a
-> NoContinuationResourceT m b -> NoContinuationResourceT m b
forall (m :: * -> *) a b.
Monad m =>
NoContinuationResourceT m a
-> (a -> NoContinuationResourceT m b)
-> NoContinuationResourceT 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
return :: forall a. a -> NoContinuationResourceT m a
$creturn :: forall (m :: * -> *) a. Monad m => a -> NoContinuationResourceT m a
>> :: forall a b.
NoContinuationResourceT m a
-> NoContinuationResourceT m b -> NoContinuationResourceT m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
NoContinuationResourceT m a
-> NoContinuationResourceT m b -> NoContinuationResourceT m b
>>= :: forall a b.
NoContinuationResourceT m a
-> (a -> NoContinuationResourceT m b)
-> NoContinuationResourceT m b
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
NoContinuationResourceT m a
-> (a -> NoContinuationResourceT m b)
-> NoContinuationResourceT m b
Monad, forall a. NoContinuationResourceT m a
forall a.
NoContinuationResourceT m a
-> NoContinuationResourceT m a -> NoContinuationResourceT m a
forall {m :: * -> *}.
MonadPlus m =>
Monad (NoContinuationResourceT m)
forall {m :: * -> *}.
MonadPlus m =>
Alternative (NoContinuationResourceT m)
forall (m :: * -> *) a. MonadPlus m => NoContinuationResourceT m a
forall (m :: * -> *) a.
MonadPlus m =>
NoContinuationResourceT m a
-> NoContinuationResourceT m a -> NoContinuationResourceT m a
forall (m :: * -> *).
Alternative m
-> Monad m
-> (forall a. m a)
-> (forall a. m a -> m a -> m a)
-> MonadPlus m
mplus :: forall a.
NoContinuationResourceT m a
-> NoContinuationResourceT m a -> NoContinuationResourceT m a
$cmplus :: forall (m :: * -> *) a.
MonadPlus m =>
NoContinuationResourceT m a
-> NoContinuationResourceT m a -> NoContinuationResourceT m a
mzero :: forall a. NoContinuationResourceT m a
$cmzero :: forall (m :: * -> *) a. MonadPlus m => NoContinuationResourceT m a
MonadPlus, forall a.
(State# (PrimState (NoContinuationResourceT m))
-> (# State# (PrimState (NoContinuationResourceT m)), a #))
-> NoContinuationResourceT m a
forall (m :: * -> *).
Monad m
-> (forall a.
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a)
-> PrimMonad m
forall {m :: * -> *}.
PrimMonad m =>
Monad (NoContinuationResourceT m)
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState (NoContinuationResourceT m))
-> (# State# (PrimState (NoContinuationResourceT m)), a #))
-> NoContinuationResourceT m a
primitive :: forall a.
(State# (PrimState (NoContinuationResourceT m))
-> (# State# (PrimState (NoContinuationResourceT m)), a #))
-> NoContinuationResourceT m a
$cprimitive :: forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState (NoContinuationResourceT m))
-> (# State# (PrimState (NoContinuationResourceT m)), a #))
-> NoContinuationResourceT m a
PrimMonad, forall a. String -> NoContinuationResourceT m a
forall (m :: * -> *).
Monad m -> (forall a. String -> m a) -> MonadFail m
forall {m :: * -> *}.
MonadFail m =>
Monad (NoContinuationResourceT m)
forall (m :: * -> *) a.
MonadFail m =>
String -> NoContinuationResourceT m a
fail :: forall a. String -> NoContinuationResourceT m a
$cfail :: forall (m :: * -> *) a.
MonadFail m =>
String -> NoContinuationResourceT m a
MonadFail, forall a. NoContinuationResourceT m a
forall a.
NoContinuationResourceT m a -> NoContinuationResourceT m [a]
forall a.
NoContinuationResourceT m a
-> NoContinuationResourceT m a -> NoContinuationResourceT m a
forall (f :: * -> *).
Applicative f
-> (forall a. f a)
-> (forall a. f a -> f a -> f a)
-> (forall a. f a -> f [a])
-> (forall a. f a -> f [a])
-> Alternative f
forall {m :: * -> *}.
Alternative m =>
Applicative (NoContinuationResourceT m)
forall (m :: * -> *) a.
Alternative m =>
NoContinuationResourceT m a
forall (m :: * -> *) a.
Alternative m =>
NoContinuationResourceT m a -> NoContinuationResourceT m [a]
forall (m :: * -> *) a.
Alternative m =>
NoContinuationResourceT m a
-> NoContinuationResourceT m a -> NoContinuationResourceT m a
many :: forall a.
NoContinuationResourceT m a -> NoContinuationResourceT m [a]
$cmany :: forall (m :: * -> *) a.
Alternative m =>
NoContinuationResourceT m a -> NoContinuationResourceT m [a]
some :: forall a.
NoContinuationResourceT m a -> NoContinuationResourceT m [a]
$csome :: forall (m :: * -> *) a.
Alternative m =>
NoContinuationResourceT m a -> NoContinuationResourceT m [a]
<|> :: forall a.
NoContinuationResourceT m a
-> NoContinuationResourceT m a -> NoContinuationResourceT m a
$c<|> :: forall (m :: * -> *) a.
Alternative m =>
NoContinuationResourceT m a
-> NoContinuationResourceT m a -> NoContinuationResourceT m a
empty :: forall a. NoContinuationResourceT m a
$cempty :: forall (m :: * -> *) a.
Alternative m =>
NoContinuationResourceT m a
Alternative, MonadState s, MonadWriter w, forall a.
(a -> NoContinuationResourceT m a) -> NoContinuationResourceT m a
forall (m :: * -> *).
Monad m -> (forall a. (a -> m a) -> m a) -> MonadFix m
forall {m :: * -> *}.
MonadFix m =>
Monad (NoContinuationResourceT m)
forall (m :: * -> *) a.
MonadFix m =>
(a -> NoContinuationResourceT m a) -> NoContinuationResourceT m a
mfix :: forall a.
(a -> NoContinuationResourceT m a) -> NoContinuationResourceT m a
$cmfix :: forall (m :: * -> *) a.
MonadFix m =>
(a -> NoContinuationResourceT m a) -> NoContinuationResourceT m a
MonadFix)
instance (MonadReader r m) ⇒ MonadReader r (NoContinuationResourceT m) where
ask :: NoContinuationResourceT m r
ask = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall r (m :: * -> *). MonadReader r m => m r
ask
local :: forall a.
(r -> r)
-> NoContinuationResourceT m a -> NoContinuationResourceT m a
local r -> r
f (NoContinuationResourceT ReaderT (MutVar (PrimState m) (NoContinuationReleaseMap m)) m a
go) = forall (m :: * -> *) a.
ReaderT (MutVar (PrimState m) (NoContinuationReleaseMap m)) m a
-> NoContinuationResourceT m a
NoContinuationResourceT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT forall a b. (a -> b) -> a -> b
$ forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local r -> r
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT (MutVar (PrimState m) (NoContinuationReleaseMap m)) m a
go
instance MonadTrans NoContinuationResourceT where
lift :: forall (m :: * -> *) a.
Monad m =>
m a -> NoContinuationResourceT m a
lift = forall (m :: * -> *) a.
ReaderT (MutVar (PrimState m) (NoContinuationReleaseMap m)) m a
-> NoContinuationResourceT m a
NoContinuationResourceT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift
data StupidlyManyResources = StupidlyManyResources deriving stock (Int -> StupidlyManyResources -> ShowS
[StupidlyManyResources] -> ShowS
StupidlyManyResources -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [StupidlyManyResources] -> ShowS
$cshowList :: [StupidlyManyResources] -> ShowS
show :: StupidlyManyResources -> String
$cshow :: StupidlyManyResources -> String
showsPrec :: Int -> StupidlyManyResources -> ShowS
$cshowsPrec :: Int -> StupidlyManyResources -> ShowS
Show)
instance Exception StupidlyManyResources
data NoContinuationReleaseMap m = NoContinuationReleaseMap
{ forall (m :: * -> *). NoContinuationReleaseMap m -> Int
nextKey ∷ !Key
, forall (m :: * -> *).
NoContinuationReleaseMap m
-> IntMap (GeneralReleaseType (WithException m) () -> m ())
releaseActions ∷ !(IntMap (GeneralReleaseType (WithException m) () → m ()))
}
data NoContinuationReleaseKey m = NoContinuationReleaseKey
{ forall (m :: * -> *). NoContinuationReleaseKey m -> Int
index ∷ !Key
, forall (m :: * -> *).
NoContinuationReleaseKey m
-> MutVar (PrimState m) (NoContinuationReleaseMap m)
mapVar ∷ !(MutVar (PrimState m) (NoContinuationReleaseMap m))
}
instance (PrimMonad m, MonadWith m) ⇒ MonadAllocate (NoContinuationResourceT m) where
type AllocationContext (NoContinuationResourceT m) = m
type AllocationException (NoContinuationResourceT m) = WithException m
type GeneralReleaseKey (NoContinuationResourceT m) = NoContinuationReleaseKey m
generalAllocate :: forall a.
GeneralAllocate
(AllocationContext (NoContinuationResourceT m))
(AllocationException (NoContinuationResourceT m))
()
()
a
-> NoContinuationResourceT
m (GeneralReleaseKey (NoContinuationResourceT m), a)
generalAllocate (GeneralAllocate (forall x.
AllocationContext (NoContinuationResourceT m) x
-> AllocationContext (NoContinuationResourceT m) x)
-> AllocationContext
(NoContinuationResourceT m)
(GeneralAllocated
(AllocationContext (NoContinuationResourceT m))
(AllocationException (NoContinuationResourceT m))
()
()
a)
alloc) = do
GeneralAllocated a
x GeneralReleaseType (WithException m) () -> m ()
rel ← forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ (forall x.
AllocationContext (NoContinuationResourceT m) x
-> AllocationContext (NoContinuationResourceT m) x)
-> AllocationContext
(NoContinuationResourceT m)
(GeneralAllocated
(AllocationContext (NoContinuationResourceT m))
(AllocationException (NoContinuationResourceT m))
()
()
a)
alloc forall a. a -> a
id
MutVar (PrimState m) (NoContinuationReleaseMap m)
mapVar ← forall (m :: * -> *) a.
ReaderT (MutVar (PrimState m) (NoContinuationReleaseMap m)) m a
-> NoContinuationResourceT m a
NoContinuationResourceT forall r (m :: * -> *). MonadReader r m => m r
ask
Int
index ← forall (m :: * -> *) a b.
PrimMonad m =>
MutVar (PrimState m) a -> (a -> (a, b)) -> m b
atomicModifyMutVar' MutVar (PrimState m) (NoContinuationReleaseMap m)
mapVar forall a b. (a -> b) -> a -> b
$ \(NoContinuationReleaseMap{Int
IntMap (GeneralReleaseType (WithException m) () -> m ())
releaseActions :: IntMap (GeneralReleaseType (WithException m) () -> m ())
nextKey :: Int
releaseActions :: forall (m :: * -> *).
NoContinuationReleaseMap m
-> IntMap (GeneralReleaseType (WithException m) () -> m ())
nextKey :: forall (m :: * -> *). NoContinuationReleaseMap m -> Int
..}) →
( NoContinuationReleaseMap
{ nextKey :: Int
nextKey = if Int
nextKey forall a. Eq a => a -> a -> Bool
== forall a. Bounded a => a
minBound then forall e a. Exception e => e -> a
impureThrow StupidlyManyResources
StupidlyManyResources else forall a. Enum a => a -> a
pred Int
nextKey
, releaseActions :: IntMap (GeneralReleaseType (WithException m) () -> m ())
releaseActions = forall a. Int -> a -> IntMap a -> IntMap a
insert Int
nextKey GeneralReleaseType (WithException m) () -> m ()
rel IntMap (GeneralReleaseType (WithException m) () -> m ())
releaseActions
}
, Int
nextKey
)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NoContinuationReleaseKey{Int
MutVar (PrimState m) (NoContinuationReleaseMap m)
index :: Int
mapVar :: MutVar (PrimState m) (NoContinuationReleaseMap m)
mapVar :: MutVar (PrimState m) (NoContinuationReleaseMap m)
index :: Int
..}, a
x)
generalRelease :: GeneralReleaseKey (NoContinuationResourceT m)
-> AllocationContext (NoContinuationResourceT m) ()
generalRelease (NoContinuationReleaseKey{Int
MutVar (PrimState m) (NoContinuationReleaseMap m)
mapVar :: MutVar (PrimState m) (NoContinuationReleaseMap m)
index :: Int
mapVar :: forall (m :: * -> *).
NoContinuationReleaseKey m
-> MutVar (PrimState m) (NoContinuationReleaseMap m)
index :: forall (m :: * -> *). NoContinuationReleaseKey m -> Int
..}) = do
Maybe (GeneralReleaseType (WithException m) () -> m ())
m_rel ← forall (m :: * -> *) a b.
PrimMonad m =>
MutVar (PrimState m) a -> (a -> (a, b)) -> m b
atomicModifyMutVar' MutVar (PrimState m) (NoContinuationReleaseMap m)
mapVar forall a b. (a -> b) -> a -> b
$ \(NoContinuationReleaseMap{Int
IntMap (GeneralReleaseType (WithException m) () -> m ())
releaseActions :: IntMap (GeneralReleaseType (WithException m) () -> m ())
nextKey :: Int
releaseActions :: forall (m :: * -> *).
NoContinuationReleaseMap m
-> IntMap (GeneralReleaseType (WithException m) () -> m ())
nextKey :: forall (m :: * -> *). NoContinuationReleaseMap m -> Int
..}) →
( NoContinuationReleaseMap
{ releaseActions :: IntMap (GeneralReleaseType (WithException m) () -> m ())
releaseActions = forall a. Int -> IntMap a -> IntMap a
delete Int
index IntMap (GeneralReleaseType (WithException m) () -> m ())
releaseActions
, Int
nextKey :: Int
nextKey :: Int
..
}
, forall a. Int -> IntMap a -> Maybe a
IntMap.lookup Int
index IntMap (GeneralReleaseType (WithException m) () -> m ())
releaseActions
)
case Maybe (GeneralReleaseType (WithException m) () -> m ())
m_rel of
Maybe (GeneralReleaseType (WithException m) () -> m ())
Nothing → forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Just GeneralReleaseType (WithException m) () -> m ()
rel → GeneralReleaseType (WithException m) () -> m ()
rel forall a b. (a -> b) -> a -> b
$ forall e a. a -> GeneralReleaseType e a
ReleaseSuccess ()