Figuring out errors

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Figuring out errors

Edward Z. Yang
Hello all,

I've been looking at [1] and trying to make tops and bottoms
(pardon the pun) of error handling in Haskell.  I am still
uncertain of what to do.

I recognize that there are different areas of code that
may have different requirements for errors:

* Pure code that is simple enough can probably get away
  with returning Maybe a

* Pure code that has multiple failure modes (the canonical
  example is parsing) should return a Either e a.  The type
  of e is a little difficult: many standard libraries seem
  to use String, but coming from Python this seems analogous
  to the long deprecated "string exceptions", which are quick
  and easy but not long-term maintainable due to lack of an
  easy way to match for them.  This leads naturally into
  Either MyError, which is supported using throwError and
  catchError.

* However, [1] specifically warns against using this technique
  in the IO monad, and I need a way to short circuit execution
  when a crucial pure operation fails (in Python, this would have just
  been an uncaught exception).  This suggests using ErrorT on
  IO, however, [1] also claims that this is generally not a good
  idea, and suggests to use throwDyn (which actually looks like
  it's been renamed to throw)

* Unfortunately, when I've tried to use this technique, I've
  run up against the fact that throw is implemented using bottom,
  so if I do a throw in a pure function, the exception might
  not actually surface up until I'm, say, attempting to print
  its return value to IO.  Denizens on #haskell have instructed
  me to treat bottom as the bane of existence and opt for
  stacking ErrorT on IO (it would be nice to know if this was
  a good idea or bad idea)

At which point, I am most thoroughly confused.  Pointers, please!

Cheers,
Edward

[1] http://www.randomhacks.net/articles/2007/03/10/haskell-8-ways-to-report-errors
Reply | Threaded
Open this post in threaded view
|

Figuring out errors

sclv

On Aug 31, 2009, at 11:02 PM, Edward Z. Yang wrote:

> Hello all,
>
> I've been looking at [1] and trying to make tops and bottoms
> (pardon the pun) of error handling in Haskell.  I am still
> uncertain of what to do.

The problem, I think, is that it really depends on the situation. One  
also should distinguish between errors and exceptions -- errors being  
when the program/programmer is faulty, and exceptions being signals  
of expected conditions. The choice is really about when you want to  
always continue, what the appropriate level to test for failure is,  
and what to do on various exceptional conditions. I tend to think  
that pure functions should always return pure results, and error  
calls should be reserved for labeling actual error situations (i.e.  
code paths that should never be taken). Then when you want to assert  
that the result will never occur, you can write a mayToError (i.e. a  
labeled fromJust) or eitherToError function. Either String should of  
course not be used to represent a range of string exceptions, but  
should be thought of as returning a single exception (i.e. "Unable to  
Parse") with accompanying explanatory text. If you need to make sure  
that a pure value in IO doesn't contain either an error or a bottom,  
I would suggest using evaluate and rnf judiciously, both of which are  
important to understand, not just for error handling, but also for  
performance.

Cheers,
S.


> I recognize that there are different areas of code that
> may have different requirements for errors:
>
> * Pure code that is simple enough can probably get away
>   with returning Maybe a
>
> * Pure code that has multiple failure modes (the canonical
>   example is parsing) should return a Either e a.  The type
>   of e is a little difficult: many standard libraries seem
>   to use String, but coming from Python this seems analogous
>   to the long deprecated "string exceptions", which are quick
>   and easy but not long-term maintainable due to lack of an
>   easy way to match for them.  This leads naturally into
>   Either MyError, which is supported using throwError and
>   catchError.
>
> * However, [1] specifically warns against using this technique
>   in the IO monad, and I need a way to short circuit execution
>   when a crucial pure operation fails (in Python, this would have just
>   been an uncaught exception).  This suggests using ErrorT on
>   IO, however, [1] also claims that this is generally not a good
>   idea, and suggests to use throwDyn (which actually looks like
>   it's been renamed to throw)
>
> * Unfortunately, when I've tried to use this technique, I've
>   run up against the fact that throw is implemented using bottom,
>   so if I do a throw in a pure function, the exception might
>   not actually surface up until I'm, say, attempting to print
>   its return value to IO.  Denizens on #haskell have instructed
>   me to treat bottom as the bane of existence and opt for
>   stacking ErrorT on IO (it would be nice to know if this was
>   a good idea or bad idea)
>
> At which point, I am most thoroughly confused.  Pointers, please!
>
> Cheers,
> Edward
>
> [1] http://www.randomhacks.net/articles/2007/03/10/haskell-8-ways- 
> to-report-errors
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/beginners