Here's another way to do this using the built-in library functions, which may or may not be clearer than some other answers. This solution also requires only an input traversal. My first thought after I looked at your problem was that you want something like List.partition lines, which splits the list into two lists based on a given predicate. However, in your case, this predicate will be based on the index of the current element, which cannot be processed by the section, despite the index for each element.
We can create our own equivalent of this behavior using fold or foldBack. I will use foldBack here, as this means you donβt have to change lists after that (see Stevens' excellent answer). What we're going to do here is to use the fold to provide our own index along with two output lists, all as a drive. Here is a generic function that will split your list into two lists based on index n:
let gencut n input =
So, you see that we are running foldBack with the initial battery value ([], [], 0). However, since we start at the end of the list, 0, representing the current index, must be subtracted from the total length of the list to get the actual index of the current item.
Then we just check to see if the current index falls in the range n. If so, we update the drive by adding the current item for list a, leave list b alone and increase the index by 1: (elem :: a, b, index + 1). In all other cases, we do the same, but instead add an element to the list b: (a, elem :: b, index + 1).
Now you can easily create your own function, which splits the list in half, creating another function over this:
let cut input = let half = (input |> List.length) / 2 input |> gencut half
I hope this can help you!
> cut data;; val it : int list * int list = ([1; 2; 3], [4; 5; 6]) > gencut 5 data;; val it : int list * int list = ([1; 2; 3; 4; 5], [6])
EDIT: you can avoid index negation by specifying the length as the initial value of the accumulator and negating it on every cycle, rather than increasing it - perhaps easier:
let gencut n input = let results = List.foldBack( fun elem acc-> let a,b,index = acc