Generalizing Network.CGI exceptions to MonadCatchIO

Bas van Dijk v.dijk.bas at gmail.com
Mon Mar 15 17:35:50 EDT 2010


On Mon, Mar 15, 2010 at 9:59 PM, Anders Kaseorg <andersk at mit.edu> wrote:
> On Mon, 15 Mar 2010, Bas van Dijk wrote:
>> What about deprecating all the cgi exception handling functions:
>> throwCGI, catchCGI and tryCGI in favor of the CatchIO ones?
>
> Yeah, that’s basically the direction I want to go in.  This patch makes
> the new CatchIO functions work by adding a MonadCatchIO interface, without
> breaking the old ones (though the old ones get a little bit of
> generalization for free).

Yes we should do that. But in addition we can advice the users of
catchCGI to actually use the CatchIO.catch instead by adding a
deprecated pragma like:

 {-# DEPRECATED catchCGI "Use Control.Monad.CatchIO.catch instead." #-}

Or is this to rude?

Something else: which MonadCatchIO package are you proposing to use:
MonadCatchIO-mtl or MonadCatchIO-transformers? I guess the former
because cgi depends on mtl. In that case we should contact the
maintainer of MonadCatchIO-mtl and ask if he can add the following
functions: bracket_, bracketOnError and finally (types and definitions
below). Then the API is equivalent to Control.Exception. (I CCed this
message to the maintainer)

(I wrote a patch a while ago that added these to
MonadCatchIO-transformers because I needed them in my regions package.
But they are not present in MonadCatchIO-mtl)

regards,

Bas

-- | A variant of 'bracket' where the return value from the first computation
-- is not required.
bracket_ :: MonadCatchIO m
         => m a  -- ^ computation to run first (\"acquire resource\")
         -> m b  -- ^ computation to run last (\"release resource\")
         -> m c  -- ^ computation to run in-between
         -> m c  -- returns the value from the in-between computation
bracket_ before after thing = block $ do
  before
  r <- unblock thing `onException` after
  after
  return r

-- | A specialised variant of 'bracket' with just a computation to run
-- afterward.
finally :: MonadCatchIO m
        => m a -- ^ computation to run first
        -> m b -- ^ computation to run afterward (even if an exception was
               -- raised)
        -> m a -- returns the value from the first computation
thing `finally` after = block $ do
  r <- unblock thing `onException` after
  after
  return r

-- | Like 'bracket', but only performs the final action if there was an
-- exception raised by the in-between computation.
bracketOnError :: MonadCatchIO m
               => m a        -- ^ computation to run first (\"acquire
resource\")
               -> (a -> m b) -- ^ computation to run last (\"release resource\")
               -> (a -> m c) -- ^ computation to run in-between
               -> m c        -- returns the value from the in-between
computation
bracketOnError before after thing = block $ do
  a <- before
  unblock (thing a) `onException` after a


More information about the Libraries mailing list