-1

How do you write a F# recursive function that accepts a positive integer n and a list xs as input, and returns a list except first n elements in xs?

let rec something n xs = .. something 7 [1..10] = [8; 9; 10]
CTNgel
  • 75
  • 4
  • You just need to call your recursive function N times ignoring the head of your list. When that is done - the remainder of the list is what you are looking for. Have you tried to implement something? – 3615 Nov 15 '19 at 06:08
  • You return the list if n = 0, otherwise return something of n-1 and tail of xs. But why recursively? Use Seq.skip – Guran Nov 15 '19 at 07:13
  • Also partial duplicate of https://stackoverflow.com/questions/4333766/why-there-is-no-list-skip-and-list-take – Guran Nov 15 '19 at 07:13

2 Answers2

0

I don't think that recursion is the most efficient way to solve this problem, but you can do it like this:

let rec something n xs = 
    if n > List.length xs || n < 0 then failwith "incorrect parameter n - out of range"
    else if n = 0 then xs
    else something (n-1) (xs |> List.tail)

let res = something 7 [1..10]

open System
Console.WriteLine(res)
//something 7 [1..10] = [8; 9; 10]
onemorecupofcoffee
  • 2,237
  • 1
  • 15
  • 21
  • Will fail on `List.tail` with "The input list was empty.Parameter name: list" if `n` is greater than the list length. – spender Nov 15 '19 at 11:13
0

The simple answer is to use List.skip ... i.e. [0..10] |> List.skip 5

To reimplement List.skip you'd be looking at something like:

let rec listSkip n list =
    match (n, list) with
    | 0, list                 -> list
    | _, []                   -> failwith "The index is outside the legal range"
    | n, _ when n < 0         -> failwith "The index cannot be negative"
    | n, _ :: tl              -> listSkip (n - 1) tl 

As this is recursion is eligible for tail-call optimization, performance should be similar to an explicit loop.

I've avoided an explicit guard checking List.length against n because List.length requires iteration of the entire list ( which we'd have to check each round of the recursion ). Thus it's cheaper just to try and remove n items and fail if we run into an empty list before n reaches 0.

spender
  • 117,338
  • 33
  • 229
  • 351