Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>It seems the only way to make such recursive list is by using <code>Obj</code> module.</p> <h2>Copy the list and make it recursive</h2> <pre><code>let cycle lst = match lst with | [] -&gt; [] | _ -&gt; let rec get_last_cell = function | [] -&gt; assert false | _::[] as last -&gt; last | _::tl -&gt; (get_last_cell tl) in let new_lst = List.map (fun x -&gt; x) lst in let last_cell = get_last_cell new_lst in Obj.set_field (Obj.repr last_cell) 1 (Obj.repr new_lst); new_lst </code></pre> <h2>Create recursive list and then insert new cons cells</h2> <pre><code>let cycle lst = match lst with | [] -&gt; [] | hd::tl -&gt; let rec loop cell lst = match lst with | [] -&gt; () | hd::tl -&gt; let new_cell = [hd] in let new_cell_obj = Obj.repr new_cell in let cell_obj = Obj.repr cell in Obj.set_field new_cell_obj 1 (Obj.field cell_obj 1); Obj.set_field cell_obj 1 new_cell_obj; loop new_cell tl in let rec cyc_lst = hd::cyc_lst in loop cyc_lst tl; cyc_lst </code></pre> <p>The idea is pretty straightforward:</p> <ol> <li>Create recursive list <code>cyc_lst</code> with only one element.</li> <li>Insert one or more new cons cells immediately before tail of <code>cyc_lst</code>.</li> </ol> <p>Example</p> <p><code>cycle [1;2]</code></p> <ol> <li><p>Create recursive list <code>cyc_lst</code>. It is represented in memory as a self-recursive cons cell</p> <pre> let rec cyc_lst = hd::cyc_lst .--------. | | | +---+-|-+ `->| 1 | * | +---+---+ </pre></li> <li><p>Create <code>new_cell</code> using 2 as the only element</p> <pre> let new_cell = [hd] cell new_cell .--------. | | | +---+-|-+ +---+---+ `->| 1 | * | | 2 | X | +---+---+ +---+---+ </pre></li> <li><p>Set <code>new_cell</code> tail pointer to first cell</p> <pre> Obj.set_field new_cell_obj 1 (Obj.field cell_obj 1) cell new_cell .--------.--------------. | | | | +---+-|-+ +---+-|-+ `->| 1 | * | | 2 | * | +---+---+ +---+---+ </pre></li> <li><p>Set <code>cell</code> tail pointer to <code>new_cell</code></p> <pre> Obj.set_field cell_obj 1 new_cell_obj cell new_cell .-----------------------. | | | +---+---+ +---+-|-+ `->| 1 | *------->| 2 | * | +---+---+ +---+---+ </pre></li> </ol> <p>I hope GC is ok with such list manipulations. Let me know if it is not.</p>
 

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