值限制-已推断该值具有通用类型

时间:2019-04-13 01:34:09

标签: f# polymorphism value-restriction

给出以下定义

let fn (id: int) (_:string) = id

我可以创建部分应用的功能

let fnPartial = fn 1

但是将_的类型更改为非密封类型,例如IEnumerable

let fn (id: int) (_:IEnumerable) = id

导致编译错误

  

值限制。值'fnPartial'已推断为具有   通用类型       val fnPartial:('_a-> int)当'_a:> IEnumerable时,要么将'fnPartial'的参数设为显式,要么(如果您不打算这样做)   为了使其通用,请添加类型注释。 (使用内置的F#   编译器)

A bug was raised,但由于以下回应而关闭

  

是的,这是设计使然-IEnumerable在字符串所在的位置未密封,并且   这会导致值限制触发

解决方法是添加类型注释

let fn (id: int) (_:IEnumerable ) = id
let fnPartial<'a> = fn 1

有人可以解释

  1. 问题的症结所在
  2. 添加类型注释如何解决该问题

1 个答案:

答案 0 :(得分:2)

关键是不允许在F#中通用。当您部分应用功能时,结果为

要使绑定(或赋值)的左侧成为函数,必须在左侧定义参数。

您收到的错误是由于IEnumerable不够具体而无法完全定义 value 的结果。在给定IEnumerable的情况下,您不知道要进行的迭代,因此编译器无法确定该值的正确类型。

您的问题的答案如下:

  1. 问题的关键在于值不能是通用的
  2. 添加类型定义使编译器知道这不是值,而是函数或允许通用的东西。

以下是相关的MSDN文档: https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/dd233183(v=vs.100)#value-restriction