For the style part, I recommend hlint [1].<div><br></div><div>Regarding the testing, QuickCheck is excellent and I have been happy with it so far.</div><div><br></div><div>From a more general point of view, I agree with a point of view that many haskellers seem to share, but that Cale Gibbard put in words on #haskell regularly. It consists in looking at your code from a higher point of view and trying to express what you wrote in a &quot;sublanguage&quot; of primitives and combinators. He pointed to [2] for more details and examples.</div>
<div><br></div><div>Hope it helps.</div><div><br></div><div>[1] <a href="http://community.haskell.org/~ndm/hlint/">http://community.haskell.org/~ndm/hlint/</a></div><div>[2] <a href="http://contracts.scheming.org/">http://contracts.scheming.org/</a><br>
<br><div class="gmail_quote">On Tue, Mar 2, 2010 at 8:20 PM, Sean Leather <span dir="ltr">&lt;<a href="mailto:leather@cs.uu.nl">leather@cs.uu.nl</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
There are numerous threads on the Haskell Café involving rewriting, refactoring, refining, and in general improving code (for some definition of improve). I am interested in seeing examples of how Haskell code can be rewritten to make it better. Some general examples are:<br>


<ul><li>Eta-reduce</li><li>Make more pointfree</li><li>Introduce monadic operators or do-notation</li><ul><li>e.g. for Maybe, lists, State<br></li></ul><li>Eliminate monadic operators or do-notation</li><li>Generalize types</li>


<ul><li>e.g. change map to fmap, (++) to mappend<br></li></ul><li>Use instances of Functor, Applicative, Alternative, Category, Arrow, Monoid, Traversable, etc.</li><li>Use library functions from Data.List, Data.Map, Data.Set, etc.</li>


<li>Use some form of generic programming (e.g. SYB, Uniplate, EMGM, Alloy)<br></li><li>Use other libraries not included in the Platform</li></ul><br>My question is simple:<br><br>   <i>How do you rewrite your code to improve it?</i><br>


<br>You can answer this in any way you like, but I think the most useful answer is to show a reasonably small, concrete example of what your code looked like before and after. Also, please describe how you think the rewrite improves such code.<br>


<ul><li>Is it better style? More useful? More efficient?<br></li><li>Are the types (before and after) the same?</li><li>Are the semantics the same?</li><li>How did you prove or test equivalence? (e.g. Can you use equational reasoning to confirm the rewrite is valid? Did you use QuickCheck?)<br>


</li></ul><br>Here is an example that I find myself doing occasionally.<br><br>For all x, f:<br><br>x &gt;&gt;= return . f<br>--&gt;<br>fmap f x<br>or<br>f &lt;$&gt; x -- requires importing Control.Applicative<br><br>I think the right-hand side (RHS) is more concise and simpler. The types here do change: the type constructor has a Monad constraint in the left-hand side and a Functor constraint in the RHS. Types that are Monad instances are generally also Functor instances, so this is often possible. I&#39;m convinced the semantics are preserved, though I haven&#39;t proven it.<br>


<br>What&#39;s an example of a rewrite that you&#39;ve encountered?<br><br>Thanks,<br><font color="#888888">Sean<br>
</font><br>_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
<br></blockquote></div><br><br clear="all"><br>-- <br>Alp Mestanogullari<br><a href="http://alpmestan.wordpress.com/">http://alpmestan.wordpress.com/</a><br><a href="http://alp.developpez.com/">http://alp.developpez.com/</a><br>

</div>