如何在 F# 中使用可变列表?

How to work with mutable lists in F#?

我是 F# 的新手,我正在制作一个程序,该程序需要查找某个列表的给定长度的每个子列表。我不确定该怎么做,所以我阅读了 this question 并决定将答案移植到 F#。这是我拥有的:

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

编译器对一些事情感到不安:它说 List<int>List<List<int>> 没有构造函数,它说 InsertRemoveAt 没有定义。我在 microsoft docs. This tutorial 提到的 RemoveAt 中找到了这些方法,但它使用 Add 而不是 Insert,这也没有用。

在 F# 中,类型 List<'t> 是不可变的 F# 列表。它与 System.Collections.Generic.List<T> 不同,这是您链接的文档中描述的内容。

要访问后者,请打开 System.Collections.Generic 命名空间(但要注意:这将隐藏常规 F# 列表)或通过其 F# 别名 ResizeArray<'t> 引用它,这也更好地表达了它的本性。

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

(另请注意,它是 Count,而不是 Length