[Haskell-cafe] ANNOUNCE: regions-0.1.0.1

Bas van Dijk v.dijk.bas at gmail.com
Wed Dec 23 18:23:36 EST 2009


Hello,

As explained in my previous email, I generalized the DeviceRegion
monad transformer from my usb-safe package and put it in its own
package:

http://hackage.haskell.org/package/regions-0.1.0.1

Hackage does not seem to build documentation at the moment so if
you're interested please look at the source code which you can get
using:

darcs get http://code.haskell.org/~basvandijk/code/regions

The main goal of regions is to allow opening of scarce resoures and
operating on them but to prevent operating on closed resources.

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

The package provides the monad transformer:

newtype RegionT resource s (pr ∷ * → *) α

And the following operation for opening scarce resources (like files,
memory pointers, database connections, USB devices, etc.):

open ∷ (Resource resource, MonadCatchIO pr)
     ⇒ resource
     → RegionT resource s pr
         (RegionalHandle resource (RegionT resource s pr))

So you give it the resource you wish to open and it yields a
computation in the region monad that returns a handle to the opened
resource. Note that this handle is parametrized by the region itself.

Finally there's the ability to run the region:

runRegionT ∷ (Resource resource, MonadCatchIO pr)
           ⇒ (∀ s. RegionT resource s pr α)
           → pr α

'runRegionT' runs the given region and finally closes all opened
resources automatically.

Note that the 's' is quantified over the region but not over the
return value. So all values that have this 's' in their type can not
be returned from the given region. Remember that the handle to a
resource, which we got from 'open', was parametrized by the region and
so has this 's' in it. This prevents us from returning a handle to a
closed resource from this function. So it's never possible to
accidentally perform I/O with a closed resource.

There's also the ability to concurrently run a region inside another
region using:

forkTopRegion ∷ (Resource resource, MonadIO pr)
              ⇒ TopRegion resource s ()
              → RegionT resource s pr ThreadId

Alo note the packages:

http://hackage.haskell.org/package/regions-monadsfd-0.1.0.1
http://hackage.haskell.org/package/regions-monadstf-0.1.0.1

Which defines instances for the monads classes in monads-fd and
monads-tf respectively.

Finally, if you want to open your own scarce resource in a region, the
only thing you have to do is define an instance for:

class Resource resource where
    data Handle resource ∷ *

    openResource  ∷ resource → IO (Handle resource)
    closeResource ∷ Handle resource → IO ()

That's it!

I'm looking forward to see instances for file Handles, memory Ptrs,
database connections, etc.

regards,

Bas


More information about the Haskell-Cafe mailing list