Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I know that this is a bit late, and an answer was already accepted. However, I believe that a good step by step guide to making something tail recursive may be of interest to the OP or anyone else for that matter. Here are some tips that have certainly helped me out. I'm going to use a strait-forward example other than prime generation because, as others have stated, there are better ways to generate primes.</p> <p>Consider a naive implementation of a count function that will create a list of integers counting down from some <code>n</code>. This version is not tail recursive so for long lists you will encounter a stack overflow exception:</p> <pre><code>let rec countDown = function | 0 -&gt; [] | n -&gt; n :: countDown (n - 1) (* ^ |... the cons operator is in the tail position as such it is evaluated last. this drags stack frames through subsequent recursive calls *) </code></pre> <p>One way to fix this is to apply continuation passing style with a parameterized function:</p> <pre><code>let countDown' n = let rec countDown n k = match n with | 0 -&gt; k [] (* v--- this is continuation passing style *) | n -&gt; countDown (n - 1) (fun ns -&gt; n :: k ns) (* ^ |... the recursive call is now in tail position *) countDown n (fun ns -&gt; ns) (* ^ |... and we initialize k with the identity function *) </code></pre> <p>Then, refactor this parameterized function into a specialized representation. Notice that the function <code>countDown'</code> is not actually counting down. This is an artifact of the way the continuation is built up when <code>n &gt; 0</code> and then evaluated when <code>n = 0</code>. If you have something like the first example and you can't figure out how to make it tail recursive, what I'm suggesting is that you write the second one and then try to optimize it to eliminate the function parameter <code>k</code>. That will certainly improve the readability. This is an optimization of the second example:</p> <pre><code>let countDown'' n = let rec countDown n ns = match n with | 0 -&gt; List.rev ns (* reverse so we are actually counting down again *) | n -&gt; countDown (n - 1) (n :: ns) countDown n [] </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload