<br><div><span class="gmail_quote">On 8/29/07, <b class="gmail_sendername">David Frey</b> &lt;<a href="mailto:dpfrey@shaw.ca">dpfrey@shaw.ca</a>&gt; wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hello Haskellers,<br><br>I have been trying to learn a bit about Haskell by solving Project Euler<br>problems.&nbsp;&nbsp;For those of you who don&#39;t know what Project Euler is, see<br><a href="http://projecteuler.net">http://projecteuler.net
</a><br><br>After solving problem 21, which is related to amicable pairs, I decided<br>to attempt problem 95 since it is an extension of the same topic.<br><br>The full description of problem 95 is here:<br><a href="http://projecteuler.net/index.php?section=problems&amp;id=95">
http://projecteuler.net/index.php?section=problems&amp;id=95</a><br><br>This is the summary:<br>&quot;Find the smallest member of the longest amicable chain with no element<br>exceeding one million.&quot;<br><br>I have attempted to solve this problem, but my solution is too resource
<br>hungry to search the full set of 1000000 numbers.<br><br>I am hoping someone reading this list can suggest :<br> - How I can improve my algorithm<br> - An alternative algorithm that will be more efficient<br> - Ways to profile a Haskell program to help me understand why my
<br>&nbsp;&nbsp; implementation is performing poorly.<br><br>In addition to the question above, I would also be interested in<br>comments on the style of the code.&nbsp;&nbsp;If there is a more idiomatic way to<br>write portions of the code, I would like to see what it is.
<br><br>My solution is at the bottom of this e-mail.&nbsp;&nbsp;The program will probably<br>run obscenely slow&nbsp;&nbsp;or die from stack overflow unless you replace<br>[1..999999] with [1..somethingSmaller]&nbsp;&nbsp;in main.<br><br>Thanks,<br>David Frey
</blockquote><div><br>Hi David,<br><br>Project Euler is a good way to learn some Haskell, although it does tend to give you a crash course in understanding laziness, efficiency and such in Haskell (whether that&#39;s good or bad depends on your point of view!). 
<br><br>All you need to do to stop your program from overflowing the stack is to change foldl to foldl&#39; in the definition of main (foldl&#39; is in Data.List so you&#39;ll also have to import that).&nbsp; The problem with foldl is that since Haskell is lazy, instead of evaluating things as it goes along, it builds up a huge string of thunks (=unevaluated expressions) and doesn&#39;t even start evaluating anything until it reaches the end of the list, which can easily blow the stack.&nbsp; foldl&#39; is a strict version of foldl which forces evaluation to take place as it goes along.&nbsp; For an excellent explanation of all of this, I suggest you read 
<a href="http://haskell.org/haskellwiki/Stack_overflow">http://haskell.org/haskellwiki/Stack_overflow</a>.<br><br>As soon as I replaced foldl with foldl&#39; in your code, it no longer overflows the stack -- however, it&#39;s still quite slow!&nbsp; I didn&#39;t wait long enough for it to finish when I ran it up to a million.&nbsp; I don&#39;t have any advice on that front at the moment, perhaps someone else will come along with a suggestion or two.&nbsp; In the meantime, you can poke around 
<a href="http://haskell.org/haskellwiki/Performance">http://haskell.org/haskellwiki/Performance</a> to see if it gives you any ideas.<br><br>Hope this helps,<br>-Brent<br></div></div>