-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Provides the region monad for safely opening and working with scarce resources. -- -- This package provides the region monad transformer. Scarce resources -- like files, memory pointers or USB devices for example can be opened -- in a region. When the region terminates, all opened resources will be -- automatically closed. The main advantage of regions is that the opened -- resources can not be returned from the region which ensures no I/O -- with closed resources is possible. -- -- The primary technique used in this package is called "Lightweight -- monadic regions" which was invented by Oleg Kiselyov and Chung-chieh -- Shan. See: -- -- http://okmij.org/ftp/Haskell/regions.html#light-weight -- -- Also see the regions-mtl and regions-monadstf -- packages which provide instances for the classes in the respected -- monad transformers packages. -- -- For an example on how to use this library see the -- safer-file-handles, usb-safe or -- regional-pointers packages. @package regions @version 0.11 -- | This module is not intended for end-users. It should only be used by -- library authors wishing to extend this regions library. module Control.Monad.Trans.Region.OnExit -- | An IO computation that closes or finalizes a resource. For -- example "hClose someHandle" or "free somePtr". type Finalizer = IO () -- | A handle to a Finalizer that allows you to duplicate it to a -- parent region using dup. -- -- Duplicating a finalizer means that instead of it being performed when -- the current region terminates it is performed when the parent region -- terminates. data FinalizerHandle r :: (* -> *) -- | Register the Finalizer in the region. When the region -- terminates all registered finalizers will be perfomed if they're not -- duplicated to a parent region. -- -- Note that finalizers are run in LIFO order (Last In First Out). So -- executing the following: -- --
-- runRegionT $ do -- _ <- onExit $ putStrLn "finalizer 1" -- _ <- onExit $ putStrLn "finalizer 2" -- return () ---- -- yields: -- --
-- finalizer 2 -- finalizer 1 --onExit :: MonadIO pr => Finalizer -> RegionT s pr (FinalizerHandle (RegionT s pr)) module Control.Monad.Trans.Region.Unsafe -- | Convert a Local region to a regular region. -- -- This function is unsafe because it allows you to use a -- LocalRegion-tagged handle outside its Local region. unsafeStripLocal :: RegionT (Local s) pr α -> RegionT s pr α unsafeLiftControlIO :: RegionControlIO m => (RunInBase m IO -> IO α) -> m α unsafeLiftControl :: Monad pr => (Run (RegionT s) -> pr α) -> RegionT s pr α unsafeControlIO :: RegionControlIO m => (RunInBase m IO -> IO (m α)) -> m α unsafeLiftIOOp :: RegionControlIO m => ((α -> IO (m β)) -> IO (m γ)) -> ((α -> m β) -> m γ) unsafeLiftIOOp_ :: RegionControlIO m => (IO (m α) -> IO (m β)) -> (m α -> m β) -- | This modules implements a technique called "Lightweight monadic -- regions" invented by Oleg Kiselyov and Chung-chieh Shan -- -- See: http://okmij.org/ftp/Haskell/regions.html#light-weight module Control.Monad.Trans.Region -- | A monad transformer in which scarce resources can be opened. When the -- region terminates, all opened resources will be closed automatically. -- It's a type error to return an opened resource from the region. The -- latter ensures no I/O with closed resources is possible. data RegionT s pr α -- | Execute a region inside its parent region pr. -- -- All resources which have been opened in the given region and which -- haven't been duplicated using dup, will be closed on exit from -- this function wether by normal termination or by raising an exception. -- -- Also all resources which have been duplicated to this region from a -- child region are closed on exit if they haven't been duplicated -- themselves. -- -- Note the type variable s of the region wich is only -- quantified over the region itself. This ensures that all -- values, having a type containing s, can not be -- returned from this function. (Note the similarity with the ST -- monad.) -- -- Note that it is possible to run a region inside another region. runRegionT :: RegionControlIO pr => (forall s. RegionT s pr α) -> pr α -- | Regions do not have an instance for MonadControlIO since that -- would break the safety guarantees. (Think about lifting -- forkIO into a region!) -- -- However runRegionT and other operations on regions do need the -- ability to lift control operations. This is where the -- RegionControlIO class comes in. This class is identical to -- MonadControlIO but its unsafeLiftControlIO method is not -- exported by this module. So user can't accidentally break the safety. -- -- Note that a RegionT is an instance of this class. For the rest -- there is a catch-all instance MonadControlIO m => -- RegionControlIO m. class MonadIO m => RegionControlIO m -- | Duplicate an h in the parent region. This h will -- usually be some type of regional handle. -- -- For example, suppose you run the following region: -- --
-- runRegionT $ do ---- -- Inside this region you run a nested child region like: -- --
-- r1hDup <- runRegionT $ do ---- -- Now in this child region you open the resource r1: -- --
-- r1h <- open r1 ---- -- ...yielding the regional handle r1h. Note that: -- --
-- r1h :: RegionalHandle (RegionT cs (RegionT ps ppr)) ---- -- where cs is bound by the inner (child) runRegionT -- and ps is bound by the outer (parent) runRegionT. -- -- Suppose you want to use the resulting regional handle r1h in -- the parent region. You can't simply return r1h because -- then the type variable cs, escapes the inner region. -- -- However, if you duplicate the regional handle you can safely return -- it. -- --
-- r1hDup <- dup r1h -- return r1hDup ---- -- Note that r1hDup :: RegionalHandle (RegionT ps ppr) -- -- Back in the parent region you can safely operate on r1hDup. class Dup h dup :: (Dup h, MonadIO ppr) => h (RegionT cs (RegionT ps ppr)) -> RegionT cs (RegionT ps ppr) (h (RegionT ps ppr)) -- | The AncestorRegion class is used to relate the region in -- which a resource was opened to the region in which it is used. Take -- the following operation from the safer-file-handles package -- as an example: -- --
-- hFileSize :: (pr `AncestorRegion` cr, MonadIO cr) => RegionalFileHandle ioMode pr -> cr Integer ---- -- The AncestorRegion class defines the parent / child -- relationship between regions. The constraint -- --
-- pr `AncestorRegion` cr ---- -- is satisfied if and only if cr is a sequence of zero or more -- "RegionT s" (with varying s) applied to -- pr, in other words, if cr is an (improper) nested -- subregion of pr. -- -- The class constraint InternalAncestorRegion pr cr serves two -- purposes. First, the instances of InternalAncestorRegion do -- the type-level recursion that implements the relation specified above. -- Second, since it is not exported, user code cannot add new instances -- of AncestorRegion (as these would have to be made instances of -- InternalAncestorRegion, too), effectively turning it into a -- closed class. class InternalAncestorRegion pr cr => AncestorRegion pr cr -- | The RootRegion is the ancestor of any region. -- -- It's primary purpose is to tag regional handles which don't have an -- associated finalizer. For example the standard file handles -- stdin, stdout and stderr which are opened -- on program startup and which shouldn't be closed when a region -- terminates. Another example is the nullPtr which is a memory -- pointer which doesn't point to any allocated memory so doesn't need to -- be freed. data RootRegion α -- | A LocalRegion is used to tag regional handles which are -- created locally. -- -- An example is the LocalPtr in the alloca function -- from the regional-pointers package: -- --
-- alloca :: (Storable a, MonadControlIO pr) -- => (forall sl. LocalPtr a (LocalRegion sl s) -> RegionT (Local s) pr b) -- -> RegionT s pr b ---- -- The finalisation of the LocalPtr is not performed by the -- regions library but is handled locally by alloca -- instead. -- -- The type variable sl, which is only quantified over the -- continuation, ensures that locally opened resources don't escape. data LocalRegion sl s α -- | A type used to tag regions in which locally created handles (handles -- tagged with LocalRegion) can be used. -- -- Note than any handle which is created in a RegionT (Local s) -- can be used outside that region (RegionT s) and visa versa -- (except for LocalRegion-tagged handles). data Local s -- | Lift a callCC operation to the new monad. liftCallCC :: (((α -> pr β) -> pr α) -> pr α) -> (((α -> RegionT s pr β) -> RegionT s pr α) -> RegionT s pr α) -- | Transform the computation inside a region. mapRegionT :: (m α -> n β) -> (RegionT s m α -> RegionT s n β) -- | Lift a catchError operation to the new monad. liftCatch :: (pr α -> (e -> pr α) -> pr α) -> (RegionT s pr α -> (e -> RegionT s pr α) -> RegionT s pr α)