<div dir="ltr"><br><br><div class="gmail_quote">On Tue, Dec 8, 2009 at 11:51 AM, Gregory Crosswhite <span dir="ltr">&lt;<a href="mailto:gcross@phys.washington.edu">gcross@phys.washington.edu</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div style="word-wrap: break-word;"><div>Michael,</div><div><br></div><div>Although I like the idea of improving the way that failures are handled in Haskell, I am having trouble seeing any reason to use your framework.</div>
<div><br></div><div>If a function is always assumed to succeed given certain pre-conditions, and somewhere along the lines my code discovers that one of these had been violated, then I throw an exception in order to communicate to myself the manner in which I screwed up.</div>
<div><br></div><div>If a function might either succeed or fail for a very specific reason, then I use a Maybe because the caller will know exactly what problem is being signaled by Nothing.</div><div><br></div><div>If a function might fail for one of many reasons and the caller might care about learning more about the problem, then I use an Either so that I can report the details of the problem.</div>
<div><br></div><div>In each of the latter two cases, I can already use monads to handle the errors in a relatively convenient manner.  In the first case I usually want the program to die right away and let me know where I screwed up, but if for some reason I wanted to continue even given arbitrary unanticipated problems in a particular computation the I use an exception handler.</div>
<div><br></div><div>Given that all of the scenarios that I encounter are already handled by the functionality the standard libraries, it is not clear to me what your framework actually offers.</div><div><br></div><div>I am not writing this to shoot your framework down, but rather to voice my thoughts aloud in order to hear your response to them, since if there is a use scenario that I am missing in which your framework would be ideal then I would be interested in hearing about it.</div>
<br></div></blockquote><div>The failure wiki page addresses exactly why Maybe and Either are inadequate solutions in a number of circumstances. Maybe does not allow any information to be attached; that may be fine when you directly call a function, but what if you call a function, which calls another one, and so on and so forth? You would then have two choices:<br>
<br>* Ultimately just receive a Nothing and not know why.<br>* At each step of the why, check if it&#39;s a Nothing, and then produce some appropriate message to describe it.<br><br>If you choose option 2, you&#39;re admitting that Maybe was not sufficient for your uses any.  Regarding Either, there are a number of issues:<br>
<br>* There *is* not Monad instance in the base library. Orphan instances lead to major issues, such as not being able to import two modules at the same time because each declares a Monad Either instance.<br>* With Either, you are limited to a single error type (unless you use existential types).<br>
* There is no easy way to chain together different types of Eithers (see below).<br><br>For example, let&#39;s say I want to write some code to authenticate a user via OpenID (see the authenticate package). It has to do at least two things:<br>
<br>* Download pages by HTTP<br>* Parse the resulting HTML page.<br><br>I would like to ideally do the following:<br><br>authenticate = do<br>  page &lt;- getPage url<br>  parsed &lt;- parseHtml page<br>  checkResult parsed<br>
<br>In other words, easily chain things together, and simply let the error types propogate. If the given functions had these signatures:<br><br>getPage :: (MonadFailure HttpException m, MonadIO m) =&gt; String -&gt; m String<br>
parseHtml :: Failure ParseHtmlException m =&gt; String -&gt; m HtmlTree<br>checkResult :: Failure AuthenticationException m =&gt; HtmlTree -&gt; m Identifier<br><br>Then authenticate would simply subsume all these error types, making it explicit what a client of the libraries needs to be aware of. If clients instead want to look at it as a simple success/failure, I would recommend using the attempt package. If they want to deal with each failure type separately, they could use control-monad-exception.<br>
<br>I hope that clears up why this package exists. It was not born of nothing; it is meant to solve real problems in an elegant manner. If you have any questions, please let me know.<br><br>Michael<br></div></div></div>