Johannes Waldmann | 7 Oct 14:58
Favicon

Control.Exception

with 6.10, the following does not typecheck:

foo `Control.Exception.catch` \ _ -> return bar

Ambiguous type variable `e' in the constraint:
      `Control.Exception.Exception e'

It is probably bad programming style anyway but what is the workaround?
I found some references (in list emails) to catchAny, ignoreExceptions
but these don't seem to have made it?

Best regards, J.W.

_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users <at> haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Thomas Schilling | 7 Oct 16:25
Gravatar

Re: Control.Exception

2008/10/7 Johannes Waldmann <waldmann <at> imn.htwk-leipzig.de>:
> with 6.10, the following does not typecheck:
>
> foo `Control.Exception.catch` \ _ -> return bar
>
> Ambiguous type variable `e' in the constraint:
>      `Control.Exception.Exception e'

catch \(e :: SomeException) -> ...
This requires language ScopedTypeVariables (and perhaps PatternSignatures).

Of cause, you should try to be more specific about which exceptions
you want to catch as e.g., Ctrl-C and many other things are also
reported as exceptions.

>
> It is probably bad programming style anyway but what is the workaround?
> I found some references (in list emails) to catchAny, ignoreExceptions
> but these don't seem to have made it?
>
> Best regards, J.W.
>
>
> _______________________________________________
> Glasgow-haskell-users mailing list
> Glasgow-haskell-users <at> haskell.org
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>
Johannes Waldmann | 7 Oct 20:48
Favicon

Re: Control.Exception

> catch \(e :: SomeException) -> ...

So, this changes the API (from 6.8 to 6.10)?

I see there is Control.OldException (providing the "old catch")
but that still does not help me if I want my code compile
with both 6.8 and 6.10. Is there some version of catch that works both ways?

best regards, J.W.

_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users <at> haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Duncan Coutts | 7 Oct 21:54
Gravatar

Re: Control.Exception

On Tue, 2008-10-07 at 20:50 +0200, Johannes Waldmann wrote:
> > catch \(e :: SomeException) -> ...
> 
> So, this changes the API (from 6.8 to 6.10)?
> 
> I see there is Control.OldException (providing the "old catch")
> but that still does not help me if I want my code compile
> with both 6.8 and 6.10. Is there some version of catch that works both ways?

Build your package using base-3 rather than base-4.

Duncan
Ian Lynagh | 7 Oct 22:02
Gravatar

Re: Control.Exception

On Tue, Oct 07, 2008 at 12:54:55PM -0700, Duncan Coutts wrote:
> On Tue, 2008-10-07 at 20:50 +0200, Johannes Waldmann wrote:
> > > catch \(e :: SomeException) -> ...
> > 
> > So, this changes the API (from 6.8 to 6.10)?
> > 
> > I see there is Control.OldException (providing the "old catch")
> > but that still does not help me if I want my code compile
> > with both 6.8 and 6.10. Is there some version of catch that works both ways?
> 
> Build your package using base-3 rather than base-4.

Another option would be for someone to fill out
    http://darcs.haskell.org/packages/extensible-exceptions/
so that it becomes a complete replacement. Currently it only has what we
needed in GHC.

Thanks
Ian
Simon Marlow | 8 Oct 10:19

Re: Control.Exception

Johannes Waldmann wrote:
> with 6.10, the following does not typecheck:
> 
> foo `Control.Exception.catch` \ _ -> return bar
> 
> Ambiguous type variable `e' in the constraint:
>       `Control.Exception.Exception e'
> 
> It is probably bad programming style anyway but what is the workaround?

As long as you're aware that it is bad programming style.  We deliberately 
didn't include an easy way to do this, because we want people to think 
about why they need to catch *all* exceptions (most of the time it's a bug).

Cheers,
	Simon
Jason Dagit | 2 Nov 02:15

Re: Control.Exception

On Wed, Oct 8, 2008 at 1:19 AM, Simon Marlow <marlowsd <at> gmail.com> wrote:
> Johannes Waldmann wrote:
>>
>> with 6.10, the following does not typecheck:
>>
>> foo `Control.Exception.catch` \ _ -> return bar
>>
>> Ambiguous type variable `e' in the constraint:
>>      `Control.Exception.Exception e'
>>
>> It is probably bad programming style anyway but what is the workaround?
>
> As long as you're aware that it is bad programming style.  We deliberately
> didn't include an easy way to do this, because we want people to think about
> why they need to catch *all* exceptions (most of the time it's a bug).

Since the above is bad form, what should I be doing?  Could someone
please provide some examples or point me at the list of exceptions
that I can catch?  What about catching multiple types of exceptions?

Thanks,
Jason
Sigbjorn Finne | 2 Nov 03:09

Re: Control.Exception

(+1) to that request - what is the "best practices" for portable exception
handling code that straddles version 6.10, i.e. that compiles with compilers
at either side with minimal fuss? I can imagine a couple of 
alternatives, but
would like to hear what others are doing here.

thanks
--sigbjorn "likes backward code compatibility"

On 11/1/2008 18:15, Jason Dagit wrote:
> On Wed, Oct 8, 2008 at 1:19 AM, Simon Marlow <marlowsd <at> gmail.com> wrote:
>   
>> Johannes Waldmann wrote:
>>     
>>> with 6.10, the following does not typecheck:
>>>
>>> foo `Control.Exception.catch` \ _ -> return bar
>>>
>>> Ambiguous type variable `e' in the constraint:
>>>      `Control.Exception.Exception e'
>>>
>>> It is probably bad programming style anyway but what is the workaround?
>>>       
>> As long as you're aware that it is bad programming style.  We deliberately
>> didn't include an easy way to do this, because we want people to think about
>> why they need to catch *all* exceptions (most of the time it's a bug).
>>     
>
> Since the above is bad form, what should I be doing?  Could someone
> please provide some examples or point me at the list of exceptions
(Continue reading)

Thomas Schilling | 2 Nov 14:32
Gravatar

Re: Control.Exception

I think the best way to get backwards compatibility is to flesh out
and use the extensible-exceptions package that Ian started, which
models extensible exceptions on top of the old exception mechanism.
Alternatively, you can decide not to use extensible exceptions and
have your package depend on base-3 instead of base-4.

For a library, however, I don't think there's a good solution, since
most of the time changing the exception mechanism for the library will
make the library incompatible with existing clients.  I guess the best
way to deal with this is to properly use the package versioning policy
and hope that clients specify their dependencies precisely.

2008/11/2 Sigbjorn Finne <sof <at> galois.com>:
> (+1) to that request - what is the "best practices" for portable exception
> handling code that straddles version 6.10, i.e. that compiles with compilers
> at either side with minimal fuss? I can imagine a couple of alternatives,
> but
> would like to hear what others are doing here.
>
> thanks
> --sigbjorn "likes backward code compatibility"
>
> On 11/1/2008 18:15, Jason Dagit wrote:
>>
>> On Wed, Oct 8, 2008 at 1:19 AM, Simon Marlow <marlowsd <at> gmail.com> wrote:
>>
>>>
>>> Johannes Waldmann wrote:
>>>
>>>>
(Continue reading)

Duncan Coutts | 2 Nov 15:44
Gravatar

Re: Control.Exception

On Sat, 2008-11-01 at 19:09 -0700, Sigbjorn Finne wrote:
> (+1) to that request - what is the "best practices" for portable exception
> handling code that straddles version 6.10, i.e. that compiles with compilers
> at either side with minimal fuss? I can imagine a couple of 
> alternatives, but
> would like to hear what others are doing here.

As far as I know there is no nice easy way to be compatible with both
models. There's no subset you can stick to that works with both.

In libraries like Cabal and other libs we've done things like:

catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
#ifdef BASE4
catchIO = Exception.catch
#else
catchIO = Exception.catchJust Exception.ioErrors
#endif

catchExit :: IO a -> (ExitCode -> IO a) -> IO a
#ifdef BASE4
catchExit = Exception.catch
#else
catchExit = ... etc ...
#endif

The point is, the old catch deals with just one exception type, while
the new one works with various kinds of specific exception types. So
you'd need one of these ifdefs for each type of exception you're
catching.
(Continue reading)

Simon Marlow | 3 Nov 14:24

Re: Control.Exception

Jason Dagit wrote:
> On Wed, Oct 8, 2008 at 1:19 AM, Simon Marlow <marlowsd <at> gmail.com> wrote:
>> Johannes Waldmann wrote:
>>> with 6.10, the following does not typecheck:
>>>
>>> foo `Control.Exception.catch` \ _ -> return bar
>>>
>>> Ambiguous type variable `e' in the constraint:
>>>      `Control.Exception.Exception e'
>>>
>>> It is probably bad programming style anyway but what is the workaround?
>> As long as you're aware that it is bad programming style.  We deliberately
>> didn't include an easy way to do this, because we want people to think about
>> why they need to catch *all* exceptions (most of the time it's a bug).
> 
> Since the above is bad form, what should I be doing?  Could someone
> please provide some examples or point me at the list of exceptions
> that I can catch?  What about catching multiple types of exceptions?

Let's distinguish two kinds of exception handling:

1. Cleaning up.  If you want to catch errors in order to clean up - release 
resources, remove temporary files, that sort of thing - then use bracket or 
finally.  Behind the scenes, these catch all exceptions, but crucially they 
re-throw the exception after cleaning up, and they do the right 
block/unblock stuff for asynchronous exceptions.

2. Recovery.  You want to catch certain kinds of exception in order to 
recover and do something else, e.g. when calling getEnv.  In that case, I 
recommend using try or tryJust.
(Continue reading)

Jason Dagit | 3 Nov 16:34

Re: Control.Exception

On Mon, Nov 3, 2008 at 6:24 AM, Simon Marlow <marlowsd <at> gmail.com> wrote:
> Jason Dagit wrote:
>>
>> On Wed, Oct 8, 2008 at 1:19 AM, Simon Marlow <marlowsd <at> gmail.com> wrote:
>>>
>>> Johannes Waldmann wrote:
>>>>
>>>> with 6.10, the following does not typecheck:
>>>>
>>>> foo `Control.Exception.catch` \ _ -> return bar
>>>>
>>>> Ambiguous type variable `e' in the constraint:
>>>>     `Control.Exception.Exception e'
>>>>
>>>> It is probably bad programming style anyway but what is the workaround?
>>>
>>> As long as you're aware that it is bad programming style.  We
>>> deliberately
>>> didn't include an easy way to do this, because we want people to think
>>> about
>>> why they need to catch *all* exceptions (most of the time it's a bug).
>>
>> Since the above is bad form, what should I be doing?  Could someone
>> please provide some examples or point me at the list of exceptions
>> that I can catch?  What about catching multiple types of exceptions?
>
> Let's distinguish two kinds of exception handling:

Thanks.  This helps a lot.  Mind if I put it somewhere, such as on the wiki?

(Continue reading)

Antoine Latter | 3 Nov 17:05

Re: Control.Exception

On Mon, Nov 3, 2008 at 9:34 AM, Jason Dagit <dagit <at> codersbase.com> wrote:
>
> Ah, but I had one more question that I don't think anyone has answered
> yet.  That is, how to deal with multiple types of exceptions.
> Suppose, as a concrete example, that I was looking out for both
> ExitCode and PatternMatchFail exceptions.  Maybe I'm being naive, but
> it seems like I'm in that situation again where I have to catch all
> and then check if fromException succeeds on either PatternMatchFile or
> ExitCode types.  And then throw if it both give Nothing?
>

I haven't tried this, so it may not work:

>>>>
data MyException = MyArithException ArithException  | MyIOException
IOException deriving Typeable

instance Exception MyExcpetion where
  toException (MyArithException e) = toException e
  toException (MyIOExcpetion e) = toException e

  fromException se = case fromException se of
           Just e -> Just $ MyArithException e
           Nothing -> case fromException se of
                 Just e -> Just $ MyIOException e
                 _ -> Nothing
<<<<<

Then anyone can catch your exceptions by catching the ArithException
or IOException as normal, and you can catch IOExceptions and
(Continue reading)

Sigbjorn Finne | 3 Nov 18:26

Re: Control.Exception

On 11/3/2008 07:34, Jason Dagit wrote:
> ....
>
> Ah, but I had one more question that I don't think anyone has answered
> yet.  That is, how to deal with multiple types of exceptions.
> Suppose, as a concrete example, that I was looking out for both
> ExitCode and PatternMatchFail exceptions.  Maybe I'm being naive, but
> it seems like I'm in that situation again where I have to catch all
> and then check if fromException succeeds on either PatternMatchFile or
> ExitCode types.  And then throw if it both give Nothing?
>
>   
One way to do this now is to use Control.Exception.catches:

 catches :: IO a -> [Handler a] -> IO a
 data Handler a where
    Handler :: forall a e. (Exception e) => (e -> IO a) -> Handler a

--sigbjorn
Duncan Coutts | 3 Nov 18:53
Gravatar

Re: Control.Exception

On Mon, 2008-11-03 at 09:26 -0800, Sigbjorn Finne wrote:
> On 11/3/2008 07:34, Jason Dagit wrote:
> > ....
> >
> > Ah, but I had one more question that I don't think anyone has answered
> > yet.  That is, how to deal with multiple types of exceptions.
> > Suppose, as a concrete example, that I was looking out for both
> > ExitCode and PatternMatchFail exceptions.  Maybe I'm being naive, but
> > it seems like I'm in that situation again where I have to catch all
> > and then check if fromException succeeds on either PatternMatchFile or
> > ExitCode types.  And then throw if it both give Nothing?
> >
> >   
> One way to do this now is to use Control.Exception.catches:
> 
>  catches :: IO a -> [Handler a] -> IO a
>  data Handler a where
>     Handler :: forall a e. (Exception e) => (e -> IO a) -> Handler a

ie:

action
  `catches`
    [ \(e :: ExitCode) -> ...
    , \(e :: PatternMatchFail) -> ...
    ]

or just by using multiple catch clauses:

action
(Continue reading)

David Menendez | 3 Nov 23:40

Re: Control.Exception

On Mon, Nov 3, 2008 at 12:53 PM, Duncan Coutts
<duncan.coutts <at> worc.ox.ac.uk> wrote:
> On Mon, 2008-11-03 at 09:26 -0800, Sigbjorn Finne wrote:
>> One way to do this now is to use Control.Exception.catches:
>>
>>  catches :: IO a -> [Handler a] -> IO a
>>  data Handler a where
>>     Handler :: forall a e. (Exception e) => (e -> IO a) -> Handler a
>
> ie:
>
> action
>  `catches`
>    [ \(e :: ExitCode) -> ...
>    , \(e :: PatternMatchFail) -> ...
>    ]
>
> or just by using multiple catch clauses:
>
> action
>  `catch` (\(e :: ExitCode) -> ...)
>  `catch` (\(e :: PatternMatchFail) -> ...)

I don't think those are equivalent. In the second case, the
PatternMatchFail handler scopes over the ExitCode handler.

--

-- 
Dave Menendez <dave <at> zednenem.com>
<http://www.eyrie.org/~zednenem/>
(Continue reading)

shelarcy | 4 Nov 01:27

Re: Control.Exception

On Tue, 04 Nov 2008 07:40:50 +0900, David Menendez <dave <at> zednenem.com> wrote:
>> ie:
>>
>> action
>>  `catches`
>>    [ \(e :: ExitCode) -> ...
>>    , \(e :: PatternMatchFail) -> ...
>>    ]
>>
>> or just by using multiple catch clauses:
>>
>> action
>>  `catch` (\(e :: ExitCode) -> ...)
>>  `catch` (\(e :: PatternMatchFail) -> ...)
>
> I don't think those are equivalent. In the second case, the
> PatternMatchFail handler scopes over the ExitCode handler.

I think Duncan forgot to write parens. According to Ian's example,
here is an equivalent code.

(action
  `catch` (\(e :: ExitCode) -> ...))
  `catch` (\(e :: PatternMatchFail) -> ...)

http://www.haskell.org/pipermail/libraries/2008-July/010095.html

Best Regards,

--

-- 
(Continue reading)

David Menendez | 4 Nov 04:08

Re: Control.Exception

On Mon, Nov 3, 2008 at 7:27 PM, shelarcy <shelarcy <at> gmail.com> wrote:
> On Tue, 04 Nov 2008 07:40:50 +0900, David Menendez <dave <at> zednenem.com> wrote:
>>> ie:
>>>
>>> action
>>>  `catches`
>>>    [ \(e :: ExitCode) -> ...
>>>    , \(e :: PatternMatchFail) -> ...
>>>    ]
>>>
>>> or just by using multiple catch clauses:
>>>
>>> action
>>>  `catch` (\(e :: ExitCode) -> ...)
>>>  `catch` (\(e :: PatternMatchFail) -> ...)
>>
>> I don't think those are equivalent. In the second case, the
>> PatternMatchFail handler scopes over the ExitCode handler.
>
> I think Duncan forgot to write parens. According to Ian's example,
> here is an equivalent code.
>
> (action
>  `catch` (\(e :: ExitCode) -> ...))
>  `catch` (\(e :: PatternMatchFail) -> ...)
>
> http://www.haskell.org/pipermail/libraries/2008-July/010095.html

That's equivalent to the code without the parentheses, but it isn't
equivalent to the code using "catches".
(Continue reading)

Simon Marlow | 4 Nov 11:47

Re: Control.Exception

Jason Dagit wrote:
> On Mon, Nov 3, 2008 at 6:24 AM, Simon Marlow <marlowsd <at> gmail.com> wrote:
>> Jason Dagit wrote:
>>> On Wed, Oct 8, 2008 at 1:19 AM, Simon Marlow <marlowsd <at> gmail.com> wrote:
>>>> Johannes Waldmann wrote:
>>>>> with 6.10, the following does not typecheck:
>>>>>
>>>>> foo `Control.Exception.catch` \ _ -> return bar
>>>>>
>>>>> Ambiguous type variable `e' in the constraint:
>>>>>     `Control.Exception.Exception e'
>>>>>
>>>>> It is probably bad programming style anyway but what is the workaround?
>>>> As long as you're aware that it is bad programming style.  We
>>>> deliberately
>>>> didn't include an easy way to do this, because we want people to think
>>>> about
>>>> why they need to catch *all* exceptions (most of the time it's a bug).
>>> Since the above is bad form, what should I be doing?  Could someone
>>> please provide some examples or point me at the list of exceptions
>>> that I can catch?  What about catching multiple types of exceptions?
>> Let's distinguish two kinds of exception handling:
> 
> Thanks.  This helps a lot.  Mind if I put it somewhere, such as on the wiki?

A good description of how to deal with exceptions would be great to have in 
the Haddock documentation for Control.Exception - would you (or someone 
else) like to write and submit a patch?  Or failing that, just putting it 
on the wiki would be useful too.

(Continue reading)

Jason Dagit | 4 Nov 18:51

Re: Control.Exception

On Tue, Nov 4, 2008 at 2:47 AM, Simon Marlow <marlowsd <at> gmail.com> wrote:
> Jason Dagit wrote:

>> Thanks.  This helps a lot.  Mind if I put it somewhere, such as on the
>> wiki?
>
> A good description of how to deal with exceptions would be great to have in
> the Haddock documentation for Control.Exception - would you (or someone
> else) like to write and submit a patch?  Or failing that, just putting it on
> the wiki would be useful too.

I don't mind submitting a patch.  What is the URL of the repo I should download?

Thanks!
Jason
Simon Marlow | 5 Nov 10:01

Re: Control.Exception

Jason Dagit wrote:
> On Tue, Nov 4, 2008 at 2:47 AM, Simon Marlow <marlowsd <at> gmail.com> wrote:
>> Jason Dagit wrote:
> 
>>> Thanks.  This helps a lot.  Mind if I put it somewhere, such as on the
>>> wiki?
>> A good description of how to deal with exceptions would be great to have in
>> the Haddock documentation for Control.Exception - would you (or someone
>> else) like to write and submit a patch?  Or failing that, just putting it on
>> the wiki would be useful too.
> 
> I don't mind submitting a patch.  What is the URL of the repo I should download?

http://darcs.haskell.org/packages/base

and the file is Control/Exception.hs.

Cheers,
	Simon

Gmane