【问题标题】:F#: Error FS0030: Value restrictionF#:错误 FS0030:值限制
【发布时间】:2015-06-15 03:25:06
【问题描述】:

我是编程新手,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):错误 FS0030:值限制。 “它”的价值 被推断为具有泛型类型 val it : '_a 将 'it' 定义为一个简单的数据项,使其成为具有显式参数的函数,或者,如果您不打算让它 是通用的,添加一个类型注释。

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

【问题讨论】:

  • splitArrayIntoGroups 函数应该返回什么值?如果它只是产生副作用,它应该返回单位,但在这种情况下,我想它不会正常终止。

标签: f#


【解决方案1】:

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

下面是inputArray为空时退出并返回unit的版本:

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

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

【讨论】:

    猜你喜欢
    • 2010-09-29
    • 2010-11-11
    • 2011-05-03
    • 2011-02-28
    • 2020-07-29
    • 2013-01-26
    相关资源
    最近更新 更多