regions-0.2: Provides the region monad for safely opening and working with scarce resources.Source codeContentsIndex
MaintainerBas van Dijk <>
Scarce resources
Accessing the internal handle of a resource.
Parent/child relationship between regions.

WARNING: This module should not be used by end-users directly because it allows access to the internalHandle of a resource which enables them to close the resource manually, which will defeat the safety-guarantees that this package provides!

This module should only be used by library authors wishing to allow their end-users to open their resources in a region.

The only thing to do, to create a module or library that allows your users to open your resources in a region, is to define an instance for Resource for your type of resource.

Make sure not to re-export anything from this module. Either re-export things from Control.Monad.Trans.Region or tell your users to import that module directly.

class Resource resource where
data Handle resource :: *
openResource :: resource -> IO (Handle resource)
closeResource :: Handle resource -> IO ()
internalHandle :: RegionalHandle resource r -> Handle resource
class Dup α where
dup :: MonadCatchIO ppr => α (RegionT cs (RegionT ps ppr)) -> RegionT cs (RegionT ps ppr) (α (RegionT ps ppr))
class (Monad pr, Monad cr) => ParentOf pr cr
Scarce resources
class Resource resource whereSource

Class of scarce resources. A scarce resource is a resource that only one user can use at a time. (like a file, memory pointer or USB device for example).

Because of the scarcity, these resources need to be opened to grant temporary sole access to the resource. When the resource is no longer needed it should be closed a.s.a.p to grant others access to the resource.

Associated Types
data Handle resource :: *Source
openResource :: resource -> IO (Handle resource)Source
closeResource :: Handle resource -> IO ()Source
Accessing the internal handle of a resource.
internalHandle :: RegionalHandle resource r -> Handle resourceSource

Get the internal handle from the regional handle.

Warning: This function should not be exported to or used by end-users because it allows them to close the handle manually, which will defeat the safety-guarantees that this package provides!

Tip: If you enable the ViewPatterns language extension you can use internalHandle as a view-pattern as in the following example from the usb-safe package:

resetDevice :: (pr `ParentOf` cr, MonadIO cr)
            -> RegionalHandle USB.Device pr -> cr ()
resetDevice (internalHandle -> (DeviceHandle ...)) = ...
class Dup α whereSource

Duplicate an α in the parent region. This α will usually be a (RegionalHandle resource) but it can be any value "derived" from this 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 resource (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 resource (RegionT ps ppr)

Back in the parent region you can safely operate on r1hDup.

dup :: MonadCatchIO ppr => α (RegionT cs (RegionT ps ppr)) -> RegionT cs (RegionT ps ppr) (α (RegionT ps ppr))Source
show/hide Instances
Resource resource => Dup (RegionalHandle resource)
Parent/child relationship between regions.
class (Monad pr, Monad cr) => ParentOf pr cr Source

The ParentOf class declares the parent/child relationship between regions.

A region is the parent of another region if they're either equivalent like:

RegionT ps pr  `ParentOf`  RegionT ps pr

or if it is the parent of the parent of the child like:

RegionT ps ppr `ParentOf` RegionT cs
                              (RegionT pcs
                                (RegionT ppcs
                                  (RegionT ps ppr)))
show/hide Instances
(Monad cr, TypeCast2 cr (RegionT s pcr), ParentOf pr pcr) => ParentOf pr cr
Monad r => ParentOf r r
Produced by Haddock version 2.6.0