【问题标题】:Why does this produce a value restriction exception?为什么这会产生值限制异常?
【发布时间】:2014-07-11 18:56:56
【问题描述】:

我创建了一个函数,它返回一个仅包含偶数索引的列表,如下所示:

let rec removeOddIdx xs =
    match xs with
    |[] -> []
    |h::t -> (if t.Length % 2 = 0 then 
                [h]@removeOddIdx t
                else 
                removeOddIdx t)

当我调用它时它工作正常:

removeOddIdx [1;2;3;];;

但是当我用一个空列表调用它时:

removeOddIdx [];;

我收到一个值限制异常 - 怎么会?
我已经阅读了价值限制,但我不明白为什么会发生这种情况。

这里是准确的错误信息:

Testing.fs(13,1):错误 FS0030:值限制。值'it' 已被推断为具有泛型类型

     val it : '_a list

'it' 定义为一个简单的数据术语,使其成为具有显式参数的函数,或者,如果您不希望它是通用的,则添加一个类型注释。

【问题讨论】:

  • 嗯,我试过了,但我没有收到任何异常、编译器错误或警告。
  • 这很奇怪。每次我运行它时都会收到错误消息(使用错误文本更新线程)。

标签: f# functional-programming f#-interactive


【解决方案1】:

您遇到的问题是编译器不知道返回值的类型。当你传递[1;2;3]它可以推断返回类型是int list,但是如果你传递它[],返回值的类型是什么?无法从用法中推断出来,因此会出现值限制错误。

一种解决方案是给参数一个像这样的类型:

> removeOddIdx ([]:int list);;
val it : int list = []

另一个是使函数具体化而不是像这样通用:

> let rec removeOddIdx (xs:int list) =
    match xs with
    |[] -> []
    |h::t -> (if t.Length % 2 = 0 then 
                [h]@removeOddIdx t
                else 
                removeOddIdx t);;

val removeOddIdx : xs:int list -> int list

> removeOddIdx [];;
val it : int list = []

在 repl 之外,这不太可能成为问题,因为参数类型很可能是从代码中的其他地方推断出来的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-16
    • 2019-10-17
    • 2014-03-31
    • 2017-01-18
    • 1970-01-01
    相关资源
    最近更新 更多