-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | CPS resource allocation but as a Monad and completely safe -- -- This implements a Monad just like Codensity from the -- `kan-extensions` package, but it uses a skolem trap just like the `ST -- s` monad to track resources allocated in the monad. The package wraps -- around different "scoped" resources that cannot escape a scoped -- block and are safely deallocated when the block is left. @package scoped-codensity @version 0.2.0.0 -- | Internal module for Scoped, ScopedResource & co. -- -- Only import this if you need to wrap an otherwise unsafe interface -- around resources module Control.Monad.Scoped.Internal -- | The Scoped monad that provides the possibility to safely scope -- the allocation of a resource -- -- It is used to abstract over all of the CPS style withSomething -- functions, like withFile -- -- Be sure to properly mask handlers if you are using -- UnsafeMkScoped. Use safe helper functions like -- registerHandler or bracketScoped where possible. -- -- Scoped also works for wrapping unboxed and unlifted monad -- transformers. newtype Scoped (s :: [Type]) (m :: k -> TYPE rep) a UnsafeMkScoped :: (forall (b :: k). () => (a -> m b) -> m b) -> Scoped (s :: [Type]) (m :: k -> TYPE rep) a -- | Unsafely runs a scoped block. Use scoped instead, otherwise -- resources might escape [unsafeRunScoped] :: Scoped (s :: [Type]) (m :: k -> TYPE rep) a -> forall (b :: k). () => (a -> m b) -> m b -- | A scoped resource with token s belonging to a Scoped -- block with the same token. -- -- If you are creating a ScopedResource, make sure the resource is -- deallocated properly when the Scoped block is exited. newtype ScopedResource s a UnsafeMkScopedResource :: a -> ScopedResource s a -- | Unsafely runs a scoped resource. It forgets the scope of the resource -- and may now be escaped incorrectly [unsafeUnwrapScopedResource] :: ScopedResource s a -> a -- | the Scoping class is there to give overloading to blocks, s.t. -- we don't have to run different functions depending on whether we run a -- final block or not. -- -- This type class is internal since there should not be any more -- instances and since it is expected that the contraint on scoped -- is immediately discharged class Scoping (ss :: [Type]) (m :: k -> TYPE r) (n :: Type -> Type) | n -> m ss -- | Run a Scoped block safely, making sure that none of the safely -- allocated resources can escape it, using the same trick as ST -- -- All of the allocated resources will live until the end of the block is -- reached scoped :: Scoping ss m n => (forall s. () => Scoped (s ': ss) m a) -> n a -- | Run a handler masked for async exception when the Scoped block -- ends -- -- You can register a handler wherever in your Scoped block you -- want, but it will nonetheless be run in reverse order that the -- handlers have been registered, after the scoped block's actions have -- been finished -- -- Mind that this uses finally under the hood and thus does not -- mask the handler with an uninterruptible mask registerHandler :: forall m a (ss :: [Type]). MonadUnliftIO m => m a -> Scoped ss m () -- | when using a resource, all that matters is that the resource can only -- be used in the scope that it was created in or any scope that is -- farther in than that scope -- -- This constraint has to be put to connect the resource and the scope -- that it was created in class s :< (ss :: [Type]) -- | A wrapper around bracket to allocate a resource safely in a -- Scoped block -- -- It returns a ScopedResource that belongs to the Scoped -- block it was allocated in -- -- Note that this uses bracket internally and thus uses an -- interruptible mask for the cleanup continuation bracketScoped :: forall m a b s (ss :: [Type]). MonadUnliftIO m => m a -> (a -> m b) -> Scoped (s ': ss) m (ScopedResource s a) instance s Control.Monad.Scoped.Internal.:< '[s] instance s Control.Monad.Scoped.Internal.:< (s : s'' : ss) instance (s Control.Monad.Scoped.Internal.:< (s'' : ss)) => s Control.Monad.Scoped.Internal.:< (s' : s'' : ss) instance forall k (m' :: GHC.Types.Type -> GHC.Types.Type) (m :: k -> GHC.Types.Type) (s :: [GHC.Types.Type]). (GHC.Internal.Base.Alternative m', m' GHC.Types.~~ m) => GHC.Internal.Base.Alternative (Control.Monad.Scoped.Internal.Scoped s m) instance forall k (s :: [GHC.Types.Type]) (m :: k -> GHC.Types.Type). GHC.Internal.Base.Applicative (Control.Monad.Scoped.Internal.Scoped s m) instance GHC.Classes.Eq a => GHC.Classes.Eq (Control.Monad.Scoped.Internal.ScopedResource s a) instance forall k (s :: [GHC.Types.Type]) (m :: k -> GHC.Types.Type). GHC.Internal.Base.Functor (Control.Monad.Scoped.Internal.Scoped s m) instance forall k (m' :: GHC.Types.Type -> GHC.Types.Type) (m :: k -> GHC.Types.Type) (s :: [GHC.Types.Type]). (GHC.Internal.Control.Monad.Fail.MonadFail m', m' GHC.Types.~~ m) => GHC.Internal.Control.Monad.Fail.MonadFail (Control.Monad.Scoped.Internal.Scoped s m) instance forall k (m' :: GHC.Types.Type -> GHC.Types.Type) (m :: k -> GHC.Types.Type) (s :: [GHC.Types.Type]). (Control.Monad.IO.Class.MonadIO m', m' GHC.Types.~~ m) => Control.Monad.IO.Class.MonadIO (Control.Monad.Scoped.Internal.Scoped s m) instance forall k (m' :: GHC.Types.Type -> GHC.Types.Type) (m :: k -> GHC.Types.Type) (s :: [GHC.Types.Type]). (GHC.Internal.Base.Alternative m', m' GHC.Types.~~ m) => GHC.Internal.Base.MonadPlus (Control.Monad.Scoped.Internal.Scoped s m) instance forall k (s :: [GHC.Types.Type]) (m :: k -> GHC.Types.Type). GHC.Internal.Base.Monad (Control.Monad.Scoped.Internal.Scoped s m) instance Control.Monad.Trans.Class.MonadTrans (Control.Monad.Scoped.Internal.Scoped s) instance GHC.Classes.Ord a => GHC.Classes.Ord (Control.Monad.Scoped.Internal.ScopedResource s a) instance GHC.Internal.Base.Monad m => Control.Monad.Scoped.Internal.Scoping (s : ss) m (Control.Monad.Scoped.Internal.Scoped (s : ss) m) instance (GHC.Internal.Base.Applicative m, m GHC.Types.~ n, l GHC.Types.~ '[]) => Control.Monad.Scoped.Internal.Scoping l m n instance GHC.Internal.Show.Show a => GHC.Internal.Show.Show (Control.Monad.Scoped.Internal.ScopedResource s a) -- | Functions and types for safely working with Handles in -- Scoped blocks module Control.Monad.Scoped.Handle -- | Just like Handle but bound to a Scoped block type ScopedHandle s = ScopedResource s Handle -- | Given a FilePath, safely allocates and deallocates a -- ScopedHandle in a Scoped block file :: forall (m :: Type -> Type) s (ss :: [Type]). MonadUnliftIO m => FilePath -> IOMode -> Scoped (s ': ss) m (ScopedHandle s) -- | See openFile data IOMode ReadMode :: IOMode WriteMode :: IOMode AppendMode :: IOMode ReadWriteMode :: IOMode -- | Like hPutStrLn but for ScopedHandle hPutStrLn :: forall (m :: Type -> Type) s (ss :: [Type]). (MonadIO m, s :< ss) => ScopedHandle s -> Text -> Scoped ss m () -- | Like hPutStr but for ScopedHandle hPutStr :: forall (m :: Type -> Type) s (ss :: [Type]). (MonadIO m, s :< ss) => ScopedHandle s -> Text -> Scoped ss m () -- | Like hGetLine but for ScopedHandle hGetLine :: forall (m :: Type -> Type) s (ss :: [Type]). (MonadIO m, s :< ss) => ScopedHandle s -> Scoped ss m Text -- | Like hGetContents but for ScopedHandle hGetContents :: forall (m :: Type -> Type) s (ss :: [Type]). (MonadIO m, s :< ss) => ScopedHandle s -> Scoped ss m Text -- | Functions and types for safely working with Asyncs in -- Scoped blocks module Control.Monad.Scoped.Async -- | Just like Async but bound to a Scoped block type ScopedAsync s a = ScopedResource s Async a -- | Run an IO action asynchronously in a Scoped block. When the -- Scoped block ends, the Async is cancelled async :: forall m a s (ss :: [Type]). MonadUnliftIO m => m a -> Scoped (s ': ss) m (ScopedAsync s a) -- | Like async but uses forkOS internally asyncBound :: forall m a s (ss :: [Type]). MonadUnliftIO m => m a -> Scoped (s ': ss) m (ScopedAsync s a) -- | Wait for the ScopedAsync to finish immediately wait :: forall (m :: Type -> Type) s (ss :: [Type]) a. (MonadIO m, s :< ss) => ScopedAsync s a -> Scoped ss m a -- | Like wait but return either Left -- SomeException or Right a waitCatch :: forall (m :: Type -> Type) s (ss :: [Type]) a. (MonadIO m, s :< ss) => ScopedAsync s a -> Scoped ss m (Either SomeException a) -- | Like wait but wait as part of the handlers of the Scoped -- block waitScoped :: forall (m :: Type -> Type) s (ss :: [Type]) a. (MonadUnliftIO m, s :< ss) => ScopedAsync s a -> Scoped ss m () -- | Like waitCatch but wait as part of the handlers of the -- Scoped block waitCatchScoped :: forall (m :: Type -> Type) s (ss :: [Type]) a. (MonadUnliftIO m, s :< ss) => ScopedAsync s a -> Scoped ss m () -- | Working with Ptrs in a way that prevents use after free -- --
--   >>> :set -XPostfixOperators
--   
--   >>> import Control.Monad.Scoped.Internal
--   
--   >>> scoped do x <- newPtr (69 :: Word); x `setPtr` 42; getPtr x
--   42
--   
module Control.Monad.Scoped.Ptr -- | A Ptr that is associated to a scope type Ptr s a = ScopedResource s Ptr a -- | this is a wrapper around withForeignPtr to allow for safe usage -- of this function in a scope foreignPtr :: forall (m :: Type -> Type) a s (ss :: [Type]). MonadUnliftIO m => ForeignPtr a -> Scoped (s ': ss) m (Ptr s a) -- | takes a function that does something with a Ptr and makes it -- safe wrapScoped :: forall m s (ss :: [Type]) a r. (Monad m, s :< ss) => (Ptr a -> m r) -> Ptr s a -> Scoped ss m r -- | Acquire mutable memory for the duration of a scope. The value is -- automatically dropped at the end of the scope. newPtr :: forall a (m :: Type -> Type) s (ss :: [Type]). (Storable a, MonadUnliftIO m) => a -> Scoped (s ': ss) m (Ptr s a) -- | write a value to a pointer setPtr :: forall a (m :: Type -> Type) s (ss :: [Type]). (Storable a, MonadIO m, s :< ss) => Ptr s a -> a -> Scoped ss m () -- | read a value from a pointer getPtr :: forall a (m :: Type -> Type) s (ss :: [Type]). (Storable a, MonadIO m, s :< ss) => Ptr s a -> Scoped ss m a -- | Functions and types for safely working with tempfiles in Scoped -- blocks module Control.Monad.Scoped.Temp -- | Like withTempFile but for Scoped tempFile :: forall (m :: Type -> Type) s (ss :: [Type]). MonadUnliftIO m => FilePath -> String -> Scoped (s ': ss) m (FilePath, ScopedHandle s) -- | Like withSystemTempFile but for Scoped systemTempFile :: forall (m :: Type -> Type) s (ss :: [Type]). MonadUnliftIO m => String -> Scoped (s ': ss) m (FilePath, ScopedHandle s) -- | The Scoped monad to safely allocate and deallocate resources. module Control.Monad.Scoped -- | The Scoped monad that provides the possibility to safely scope -- the allocation of a resource -- -- It is used to abstract over all of the CPS style withSomething -- functions, like withFile -- -- Be sure to properly mask handlers if you are using -- UnsafeMkScoped. Use safe helper functions like -- registerHandler or bracketScoped where possible. -- -- Scoped also works for wrapping unboxed and unlifted monad -- transformers. data Scoped (s :: [Type]) (m :: k -> TYPE rep) a -- | A scoped resource with token s belonging to a Scoped -- block with the same token. -- -- If you are creating a ScopedResource, make sure the resource is -- deallocated properly when the Scoped block is exited. data ScopedResource s a -- | Run a Scoped block safely, making sure that none of the safely -- allocated resources can escape it, using the same trick as ST -- -- All of the allocated resources will live until the end of the block is -- reached scoped :: Scoping ss m n => (forall s. () => Scoped (s ': ss) m a) -> n a -- | Run a handler masked for async exception when the Scoped block -- ends -- -- You can register a handler wherever in your Scoped block you -- want, but it will nonetheless be run in reverse order that the -- handlers have been registered, after the scoped block's actions have -- been finished -- -- Mind that this uses finally under the hood and thus does not -- mask the handler with an uninterruptible mask registerHandler :: forall m a (ss :: [Type]). MonadUnliftIO m => m a -> Scoped ss m () -- | when using a resource, all that matters is that the resource can only -- be used in the scope that it was created in or any scope that is -- farther in than that scope -- -- This constraint has to be put to connect the resource and the scope -- that it was created in class s :< (ss :: [Type]) -- | A Ptr that is associated to a scope type Ptr s a = ScopedResource s Ptr a -- | this is a wrapper around withForeignPtr to allow for safe usage -- of this function in a scope foreignPtr :: forall (m :: Type -> Type) a s (ss :: [Type]). MonadUnliftIO m => ForeignPtr a -> Scoped (s ': ss) m (Ptr s a) -- | takes a function that does something with a Ptr and makes it -- safe wrapScoped :: forall m s (ss :: [Type]) a r. (Monad m, s :< ss) => (Ptr a -> m r) -> Ptr s a -> Scoped ss m r -- | Acquire mutable memory for the duration of a scope. The value is -- automatically dropped at the end of the scope. newPtr :: forall a (m :: Type -> Type) s (ss :: [Type]). (Storable a, MonadUnliftIO m) => a -> Scoped (s ': ss) m (Ptr s a) -- | write a value to a pointer setPtr :: forall a (m :: Type -> Type) s (ss :: [Type]). (Storable a, MonadIO m, s :< ss) => Ptr s a -> a -> Scoped ss m () -- | read a value from a pointer getPtr :: forall a (m :: Type -> Type) s (ss :: [Type]). (Storable a, MonadIO m, s :< ss) => Ptr s a -> Scoped ss m a -- | Just like Async but bound to a Scoped block type ScopedAsync s a = ScopedResource s Async a -- | Run an IO action asynchronously in a Scoped block. When the -- Scoped block ends, the Async is cancelled async :: forall m a s (ss :: [Type]). MonadUnliftIO m => m a -> Scoped (s ': ss) m (ScopedAsync s a) -- | Like async but uses forkOS internally asyncBound :: forall m a s (ss :: [Type]). MonadUnliftIO m => m a -> Scoped (s ': ss) m (ScopedAsync s a) -- | Wait for the ScopedAsync to finish immediately wait :: forall (m :: Type -> Type) s (ss :: [Type]) a. (MonadIO m, s :< ss) => ScopedAsync s a -> Scoped ss m a -- | Like wait but return either Left -- SomeException or Right a waitCatch :: forall (m :: Type -> Type) s (ss :: [Type]) a. (MonadIO m, s :< ss) => ScopedAsync s a -> Scoped ss m (Either SomeException a) -- | Like wait but wait as part of the handlers of the Scoped -- block waitScoped :: forall (m :: Type -> Type) s (ss :: [Type]) a. (MonadUnliftIO m, s :< ss) => ScopedAsync s a -> Scoped ss m () -- | Like waitCatch but wait as part of the handlers of the -- Scoped block waitCatchScoped :: forall (m :: Type -> Type) s (ss :: [Type]) a. (MonadUnliftIO m, s :< ss) => ScopedAsync s a -> Scoped ss m () -- | Just like Handle but bound to a Scoped block type ScopedHandle s = ScopedResource s Handle -- | Given a FilePath, safely allocates and deallocates a -- ScopedHandle in a Scoped block file :: forall (m :: Type -> Type) s (ss :: [Type]). MonadUnliftIO m => FilePath -> IOMode -> Scoped (s ': ss) m (ScopedHandle s) -- | See openFile data IOMode ReadMode :: IOMode WriteMode :: IOMode AppendMode :: IOMode ReadWriteMode :: IOMode -- | Like hPutStrLn but for ScopedHandle hPutStrLn :: forall (m :: Type -> Type) s (ss :: [Type]). (MonadIO m, s :< ss) => ScopedHandle s -> Text -> Scoped ss m () -- | Like hPutStr but for ScopedHandle hPutStr :: forall (m :: Type -> Type) s (ss :: [Type]). (MonadIO m, s :< ss) => ScopedHandle s -> Text -> Scoped ss m () -- | Like hGetLine but for ScopedHandle hGetLine :: forall (m :: Type -> Type) s (ss :: [Type]). (MonadIO m, s :< ss) => ScopedHandle s -> Scoped ss m Text -- | Like hGetContents but for ScopedHandle hGetContents :: forall (m :: Type -> Type) s (ss :: [Type]). (MonadIO m, s :< ss) => ScopedHandle s -> Scoped ss m Text -- | Like withTempFile but for Scoped tempFile :: forall (m :: Type -> Type) s (ss :: [Type]). MonadUnliftIO m => FilePath -> String -> Scoped (s ': ss) m (FilePath, ScopedHandle s) -- | Like withSystemTempFile but for Scoped systemTempFile :: forall (m :: Type -> Type) s (ss :: [Type]). MonadUnliftIO m => String -> Scoped (s ': ss) m (FilePath, ScopedHandle s)