While working on the next release of data-object, I wanted to represent some operations that might fail. The typical candidates were:

1) Maybe
2) Either
3) Monad

Monad is always iffy because of the often times poorly defined fail. Maybe doesn't provide any means of reporting what the problem was. Either is not defined as a Monad in the base library. Also, the usual candidate of Either String only provides for an error message. It would be nice to have more in-depth information available.

So I've put together a package I call "attempt". It defines a data type called (surprise) Attempt with a Success and Failure constructor. The trick here is that it using the new extensible exceptions under the surface, so you can report any kind of exception you want. It also provides a "FromAttempt" type class for possible conversion targets from an Attempt, provides an attempt function with some helpers for performing the equivalent of Control.Exception.catches, and provides two samples of functions I would want to implement with this library: attemptJoin and attemptLookup.

My questions for the list are:

1) Is the overall approach sound, or do people have better ideas?
2) Are there any other FromAttempt instances I should provide out of the box?
3) I was considering adding specialized versions of the fromAttempt function, ie ioFromAttempt, maybeFromAttempt. Thoughts?
4) Should I follow the naming scheme attemptJoin, attemptLookup, etc, or just call the functions join, lookup and force people to import the module qualified?
5) Any other suggestions for attempt functions? I've considered head/tail/etc.
6) Include ToAttempt?

The code is available on github at http://github.com/snoyberg/attempt/blob/master/Data/Attempt.hs . I appreciate the review. Also, I have not yet documented the code, but I will do so before uploading to Hackage; I just didn't want to document a changing target.

Thank you,
Michael