F#:错误 FS0030:值限制

F#: Error FS0030: Value restriction

我是编程新手,F# 是我的第一语言。

以下是我的代码的相关部分:

let rec splitArrayIntoGroups (inputArray: string[]) (groupSize: int) (hashSetOfGroups: HashSet<string[]>)=
    let startIndex = 0
    let endIndex = groupSize - 1

    let group = inputArray.[startIndex .. endIndex]
    let nextInputArray = inputArray.[groupSize .. inputArray.Length - 1]

    hashSetOfGroups.Add(group) |> ignore
    splitArrayIntoGroups nextInputArray groupSize hashSetOfGroups

let hashSetOfGroups = new HashSet<string[]>()

splitArrayIntoGroups urlArray 10 hashSetOfGroups

urlArray 是一个包含近 3200 个 URL 的数组。

当我尝试 运行 F# 交互中的代码时,我收到以下错误消息:

Program.fs(119,1): error FS0030: Value restriction. The value 'it' has been inferred to have generic type val it : '_a Either define 'it' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation.

出了什么问题,我应该做出哪些改变?

就目前而言,代码将无限循环。退出条件是什么?正如@Petr 指出的那样,函数 return?

的作用是什么?

下面是当 inputArray 为空时退出和 returns 单元的版本:

let rec splitArrayIntoGroups (inputArray: string[]) (groupSize: int) (hashSetOfGroups: HashSet<string[]>)=

    match inputArray with
    | [||] -> ()
    | _ ->
        let startIndex = 0
        let endIndex = groupSize - 1
        let group = inputArray.[startIndex .. endIndex]
        let nextInputArray = inputArray.[groupSize .. inputArray.Length - 1]

        hashSetOfGroups.Add(group) |> ignore
        splitArrayIntoGroups nextInputArray groupSize hashSetOfGroups

与其使用可变集,更惯用的方法是使用 F# Set 类型,然后将新版本传递给每个递归,如下所示:

let rec splitArrayIntoGroups2 inputArray groupSize hashSetOfGroups =

    match inputArray with
    | [||] -> hashSetOfGroups 
    | _ ->
        let startIndex = 0
        let endIndex = groupSize - 1
        let group = inputArray.[startIndex .. endIndex]
        let nextInputArray = inputArray.[groupSize .. inputArray.Length - 1]

        let newSet = Set.add group hashSetOfGroups
        splitArrayIntoGroups2 nextInputArray groupSize newSet 

顺便说一句,目前的逻辑似乎与索引逻辑有关。如果我尝试以下操作:

let urlArray = [| "a"; "b"; "c"; "d" |]
let result = splitArrayIntoGroups2 urlArray 10 Set.empty

然后我得到一个 IndexOutOfRangeException

你的意思是这样的吗?

let rec splitArrayIntoGroups3 inputArray startIndex groupSize hashSetOfGroups =

    let maxIndex = Array.length inputArray - 1
    if startIndex > maxIndex  then
        hashSetOfGroups 
    else
        let endIndex = min (startIndex + groupSize - 1) maxIndex 
        let group = inputArray.[startIndex .. endIndex]
        let newSet = Set.add group hashSetOfGroups

        let nextStartIndex = endIndex + 1
        splitArrayIntoGroups3 inputArray nextStartIndex groupSize newSet 

let urlArray = [| "a"; "b"; "c"; "d"; "e"  |]
let result = splitArrayIntoGroups3 urlArray 0 2 Set.empty

请注意,此最终版本适用于任何类型的数组,而不仅仅是字符串数组。