2

I'm new to F# and I'm making a program that requires finding every sub-list of given length of some list. I wasn't sure how to go about this so I read this question and decided to port the answer to F#. Here's what I have:

let rec getSubLists (len : int) (list : List<int>) : List<List<int>> =
  let result = new List<List<int>>()
  let current = new List<int>()

  let rec findSubLists (len : int) (superSet : List<int>) (current : List<int>) (soln : List<List<int>>) (idx : int) : unit =
    if current.Length = len then soln.Insert(len - 1, current)
    elif idx = superSet.Length then
      let x = superSet.[idx] 
      current.Insert(len, x)
      findSubLists len superSet current soln (idx + 1)
      current.RemoveAt(x)
      findSubLists len superSet current soln (idx + 1)
    else ()

  findSubLists len list current result 0
  result

The compiler is upset about a few things: it says there is no constructor for List<int>, List<List<int>>, and it says that Insert and RemoveAt are not defined. I found these methods in the microsoft docs. This tutorial mentions RemoveAt, but it uses Add instead of Insert, which also didn't work.

Eben Kadile
  • 759
  • 4
  • 21

1 Answers1

8

In F# the type List<'t> is the immutable F# list. It is not the same as System.Collections.Generic.List<T>, which is what is described in the docs you linked.

To access the latter, either open the System.Collections.Generic namespace (but beware: this will shadow the regular F# list) or refer to it by its F# alias, ResizeArray<'t>, which also better expresses its true nature.

let rec getSubLists (len : int) (list : ResizeArray<int>) : ResizeArray<ResizeArray<int>> =
  let result = new ResizeArray<ResizeArray<int>>()
  let current = new ResizeArray<int>()

  let rec findSubLists (len : int) (superSet : ResizeArray<int>) (current : ResizeArray<int>) (soln : ResizeArray<ResizeArray<int>>) (idx : int) : unit =
    if current.Count = len then soln.Insert(len - 1, current)
    elif idx = superSet.Count then
      let x = superSet.[idx] 
      current.Insert(len, x)
      findSubLists len superSet current soln (idx + 1)
      current.RemoveAt(x)
      findSubLists len superSet current soln (idx + 1)
    else ()

  findSubLists len list current result 0
  result

(also note that it's Count, not Length)

Fyodor Soikin
  • 78,590
  • 9
  • 125
  • 172