|Maintainer||Bas van Dijk <firstname.lastname@example.org>|
This modules implements a technique called "Lightweight monadic regions" invented by Oleg Kiselyov and Chung-chieh Shan
- data RegionT s pr α
- runRegionT :: MonadCatchIO pr => (forall s. RegionT s pr α) -> pr α
- type TopRegion s = RegionT s IO
- runTopRegion :: (forall s. TopRegion s α) -> IO α
- forkTopRegion :: MonadIO pr => TopRegion s () -> RegionT s pr ThreadId
- class Dup α where
- module Control.Monad.Trans.Region.ParentOf
- liftCallCC :: (((α -> pr β) -> pr α) -> pr α) -> ((α -> RegionT s pr β) -> RegionT s pr α) -> RegionT s pr α
- mapRegionT :: (m α -> n β) -> RegionT s m α -> RegionT s n β
- liftCatch :: (pr α -> (e -> pr α) -> pr α) -> RegionT s pr α -> (e -> RegionT s pr α) -> RegionT s pr α
A monad transformer in which scarce resources can be opened which are automatically closed when the region terminates.
|MonadTrans (RegionT s)|
|Monad pr => Monad (RegionT s pr)|
|Functor pr => Functor (RegionT s pr)|
|MonadFix pr => MonadFix (RegionT s pr)|
|MonadPlus pr => MonadPlus (RegionT s pr)|
|Applicative pr => Applicative (RegionT s pr)|
|MonadCatchIO pr => MonadCatchIO (RegionT s pr)|
|Alternative pr => Alternative (RegionT s pr)|
|MonadIO pr => MonadIO (RegionT s pr)|
Execute a region inside its parent region
All resources which have been opened in the given region and which haven't been
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
Note that it is possible to run a region inside another region.
Return a region which executes the given top-level region in a new thread.
Note that the forked region has the same type variable
s as the resulting
region. This means that all values which can be referenced in the resulting
region can also be referenced in the forked region.
For example the following is allowed:
runRegionT $ do regionalHndl <- open resource threadId <- forkTopRegion $ doSomethingWith regionalHndl doSomethingElseWith regionalHndl
Note that the
regionalHndl and all other resources opened in the current
thread are closed only when the current thread or the forked thread terminates
whichever comes last.
α in the parent region. This
α 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
r1h <- open r1
...yielding the regional handle
r1h. Note that:
r1h :: RegionalHandle (RegionT cs (RegionT ps ppr))
cs is bound by the inner (child)
bound by the outer (parent)
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
escapes the inner region.
However, if you duplicate the regional handle you can safely return it.
r1hDup <- dup r1h return r1hDup
r1hDup :: RegionalHandle (RegionT ps ppr)
Back in the parent region you can safely operate on
Handy functions for writing monadic instances
callCC operation to the new monad.
Transform the computation inside a region.