
Hi Oleg, Just made a few modifications and thought it might be useful to people. I have rewritten the functions as "liftR" and "bracketR" over a "MonadIO" monad interface (allowing monad-transformers to be used). This is now usable as Region library, as you can lift any arbitrary IO function into a Region. I don't think I have overlooked anything, and I think it is as safe as the original... but perhaps you would like to check for stupid mistakes... The exported interface is intended to be "liftR", "bracketR" and "runR". See attached "MonadIORegion.hs"... Regards, Keean. oleg@pobox.com wrote:
This message shows a very simple implementation of Monadic Regions (for the particular case of IO and reading the file). The technique *statically* guarantees that neither a file handle nor any computation involving the handle can leak outside of the region that created it. Therefore, the handle can be safely closed (and its resources disposed of) whenever control leaves the corresponding 'withFile' block. Many handles can be open simultaneously, the type system enforces the proper nesting of their regions. The technique has no run-time overhead and induces no run-time errors. Unlike the previous implementation of monadic regions, only the basic extensions (higher-ranked types and one two-parameter type class) are used. No undecidable instances, no functional dependencies (let alone overlapping instances) are required. In fact, the implementation uses only one trivial typeclass and one trivial instance.

On 1/17/06, Keean Schupke
Just made a few modifications and thought it might be useful to people. I have rewritten the functions as "liftR" and "bracketR" over a "MonadIO" monad interface (allowing monad-transformers to be used).
I'm sorry, but what is "Lib.Monad.MonadT"? How does up3 work? MonadIO
exists in Control.Monad.Trans.
--
Taral

Taral wrote:
On 1/17/06, Keean Schupke
wrote: Just made a few modifications and thought it might be useful to people. I have rewritten the functions as "liftR" and "bracketR" over a "MonadIO" monad interface (allowing monad-transformers to be used).
I'm sorry, but what is "Lib.Monad.MonadT"? How does up3 work? MonadIO exists in Control.Monad.Trans.
It didnt when I wrote the MonadIO stuff that I use! Here is the missing file ... I tried to put it all in one, but missed the use of up3. (see attached) Regards, Keean.

On 1/18/06, Keean Schupke
It didnt when I wrote the MonadIO stuff that I use! Here is the missing file ... I tried to put it all in one, but missed the use of up3. (see attached)
All I see is "up3 = undefined"... somehow I don't think that will work.
As far as I know, (t m a -> m a) is only possible for very specific
monad transformers...
--
Taral

up3 is quite easy to define, but it is specific to the monad-transformer you are lifting through... see attached for definition for the state-monad-transformer. Keean. Taral wrote:
On 1/18/06, Keean Schupke
wrote: It didnt when I wrote the MonadIO stuff that I use! Here is the missing file ... I tried to put it all in one, but missed the use of up3. (see attached)
All I see is "up3 = undefined"... somehow I don't think that will work.
As far as I know, (t m a -> m a) is only possible for very specific monad transformers...
-- Taral
"Computer science is no more about computers than astronomy is about telescopes." -- Edsger Dijkstra

On 1/18/06, Keean Schupke
up3 is quite easy to define, but it is specific to the monad-transformer you are lifting through... see attached for definition for the state-monad-transformer.
Ah, you're using undefined for the state. If you're going to do that,
though, why not just have the function provided in the inner monad,
since the features of the transformer are not available?
--
Taral

On Tue, Jan 17, 2006 at 06:13:14PM +0000, Keean Schupke wrote:
Just made a few modifications and thought it might be useful to people. I have rewritten the functions as "liftR" and "bracketR" over a "MonadIO" monad interface (allowing monad-transformers to be used). This is now usable as Region library, as you can lift any arbitrary IO function into a Region. I don't think I have overlooked anything, and I think it is as safe as the original... [snip] liftR :: (InRegion mark marks) => (h -> m a) -> Private mark h -> Region marks m a liftR f (Private h) = Region $ f h
This is not as safe. Try modifying your test2:
-- test2 = bracketR (openFile "/etc/services" ReadMode) (hClose) (\f -> return f) -- test2' = bracketR (openFile "/etc/services" ReadMode) (hClose) (\f -> liftR return f)
This returns the "Private" handle out of the region. Still, these functions would be useful for creating a library of region-safe operations. Andrew

Andrew Pimlott wrote:
liftR :: (InRegion mark marks) => (h -> m a) -> Private mark h -> Region marks m a liftR f (Private h) = Region $ f h
This is not as safe. Try modifying your test2.
Okay, I missed this... Have renamed the function "unsafeLiftR"... As you say still useful for building libraries provided you do not export the region code from the library that uses it. Of course an alternative is just to have an opaque/abstract handle, and not export the data-constructor. Keean.
participants (3)
-
Andrew Pimlott
-
Keean Schupke
-
Taral