Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The function returns the second half of the given list.</p> <p>The interesting part of the code is only the nested (recursive) function, because the only purpose of the outer function is to call the nested function and pass it the specified list two times. The nested <code>cut</code> function has two arguments (as a tuple), so it's type is:</p> <pre><code>cut : 'a list * 'a list -&gt; 'a list </code></pre> <p>When calling itself recursively, this is the function that is called (which explains why it is called with two arguments). Here is the commented code:</p> <pre><code>// The 'function' syntax means that the arguments of the function are matched against // several clauses. When the arguments (lists) match the clause, the clause is selected // and its body will be executed. let rec cut = function // When the second list is empty or contains a single element, // the function return all elements of the first list | xs, ([] | [_]) -&gt; xs // When the first list is empty, return empty list | [], _ -&gt; [] // When first list is non-empty and second contains at least two elements, // the function takes one element from the first list and two elements from // the second list (x, y, y'), ignores them and calls itself with the // remaining lists as arguments. | x::xs, y::y'::ys -&gt; cut (xs, ys) cut ([ 1 .. 10 ], [ 1 .. 10 ]) </code></pre> <p>The idea of the function is that it iterates over two copies of the same list. At every recursive step, it skips two elements from the second one and one element from the first one. By the time it reaches the end of the second list, the first one contains the second half of the list (because the function was skipping its elements 2-times slower).</p> <p><strong>To get the first half of the list</strong> you'll need to add additional parameter to your inner recursive <code>cut</code> function. You can use it for accumulating the elements from the first list. Again, you'll need to skip over elements of one of the list two-times faster. Instead of skipping first elements of the other list, you'll need to take them and add them to your accumulator.</p> <p>I will not give you a full solution, but to give you some idea, here is pseudo-code:</p> <pre><code> | x::xs, _::_::ys -&gt; // Call 'cut' recursively to process 'xs' and 'ys' // and add the element 'x' to the accumulator. </code></pre> <p><strong>Another way</strong> to write the function would be to use <code>match</code> instead of <code>function</code> and write the two arguments as standard multiple arguments (instead of using a tuple). When ignoring elements in the last clause, it is also possible to use <code>_</code> because their names are not needed:</p> <pre><code>let rec cut l1 l2 = match l1, l2 with | xs, ([] | [_]) -&gt; xs | [], _ -&gt; [] | _::xs, _::_::ys -&gt; cut xs ys cut [ 1 .. 10 ] [ 1 .. 10 ] </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.
    3. VO
      singulars
      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