<div class="gmail_quote">On Mon, Jan 5, 2009 at 1:48 PM, Peter Robinson <span dir="ltr">&lt;<a href="mailto:thaldyron@gmail.com">thaldyron@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Hello,<br>
<br>
One thing that&#39;s been bothering me about MonadError monads is<br>
the non-portability of code that uses a custom Error type. &nbsp;Meaning, if I<br>
have libraries A and B that use different error types, I won&#39;t be able to<br>
write a function func:<br>
<br>
func = (funcA &gt;&gt; funcB) `catchError` (\e -&gt; ...)<br>
<br>
funcA :: ErrorT MyErrorA m ()<br>
<br>
funcB :: ErrorT MyErrorB m ()<br>
<br>
So I&#39;m wondering whether there&#39;s a reason not to introduce a type class<br>
hierarchy instead of custom error types to make the code more portable.</blockquote><div><br></div><div>I think this worry is related to a world view of &quot;large monads&quot;, which also proliferates claims like &quot;monads are not appropriate for large programs&quot;, and is related to fat interfaces in OOP. &nbsp;I claim that, like objects, monads are appropriate for little pieces of computations, and monadic computations <span class="Apple-style-span" style="font-style: italic;">in different</span>&nbsp;monads deserve to be composed just as much so as those in the same monad.</div>
<div><br></div><div>The complex type-directed approach gives the feel of exceptions from mainstream languages, but will run into problems when eg. two computations both use ErrorT String, but you want to differentiate the errors. &nbsp;All that is necessary is a simple function:</div>
<div><br></div><div><span class="Apple-style-span" style="font-family: &#39;courier new&#39;, monospace;">mapError :: (e -&gt; e&#39;) -&gt; ErrorT e a -&gt; ErrorT e&#39; a</span></div><div><span class="Apple-style-span" style="font-family: &#39;courier new&#39;, monospace;">mapError f = ErrorT . liftM (left f) . runErrorT</span></div>
<div><br></div><div>(Where &quot;left&quot; is from Control.Arrow, and is a &quot;semantic editor&quot;)</div><div><br></div><div>Then your example can become::</div><div><br></div><div><span class="Apple-style-span" style="font-family: &#39;courier new&#39;, monospace;">func = (mapError Left funcA &gt;&gt; mapError Right funcB) `catchError` (\e -&gt; ...)</span><br>
</div><div><br></div><div>Luke</div></div>