
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
participants (1)
-
Bas van Dijk