【问题标题】:F# value restriction in empty list空列表中的 F# 值限制
【发布时间】:2012-03-13 21:12:51
【问题描述】:

我有一个 F# 函数:

let removeEven (listToGoUnder : _ list) =
    let rec listRec list x =
        match list with
        | [] -> []
        | head::tail when (x%2 = 0) -> head :: listRec (tail) (x+1)
        | head::tail -> listRec (tail) (x+1)

     listRec listToGoUnder 0

它删除列表中偶数索引处的所有元素。 如果我给列表一些输入,它会起作用,比如removeEven ['1';'2';'3'] 我得到['1';'3'] 我应该这样做。但是当我插入一个空列表作为参数时,我得到了这个错误:

stdin(78,1):错误 FS0030:值限制。 'it' 的值是 推断具有泛型类型

val it : '_a list 将 'it' 定义为一个简单的数据项,使 它是一个带有显式参数的函数,或者,如果您不打算使用它 要通用,请添加类型注释。

帮忙,有人吗?

【问题讨论】:

    标签: list f# value-restriction


    【解决方案1】:

    空列表([])比较特别;它可以是任何类型的列表。因此,编译器会抱怨您没有[] 的特定类型。在参数上添加类型注解有助于解决问题:

    let results = removeEven ([]: int list)
    

    @kvb 建议的更多惯用类型注释:

    let results: int list = removeEven []
    

    这可能不是问题,但您的函数应命名为 removeOdd,因为索引通常从 0 开始,并且您的函数会删除所有具有奇数索引的元素。此外,如果您在列表的前两个元素上使用模式匹配,而不是使用计数器 x 来检查索引,事情就会更加清晰:

    let rec removeOdd = function
        | [] -> []
        | [x] -> [x]
        | x::_::xs -> x::removeOdd xs
    

    【讨论】:

    • 请注意,您也可以直接将注解添加到results,这可能更惯用。
    • 当参数为 [] 时,建议的 removeOdd 函数会失败。我正在尝试以通用方式解决此问题,但如果没有“错误 FS0030:值限制”,我将无法处理 [] 案例。是否有可能使这样的功能真正通用?
    猜你喜欢
    • 1970-01-01
    • 2013-01-26
    • 2011-05-03
    • 1970-01-01
    • 2020-07-29
    • 2015-06-15
    • 2010-11-11
    相关资源
    最近更新 更多