值限制 - 该值已被推断为具有泛型类型

Posted

技术标签:

【中文标题】值限制 - 该值已被推断为具有泛型类型【英文标题】:Value restriction - The value has been inferred to have generic type 【发布时间】:2019-09-03 18:54:04 【问题描述】:

给出以下定义

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

我可以创建一个部分应用的函数

let fnPartial = fn 1

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

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

导致编译错误

值限制。值“fnPartial”已被推断为 泛型 val fnPartial : ('_a -> int) when '_a :> IEnumerable 要使其通用,请添加类型注释。 (使用内置 F# 编译器)

A bug was raised 但以以下响应关闭

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

解决方法是添加类型注释

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

谁能解释一下

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

【问题讨论】:

【参考方案1】:

关键是 values 在 F# 中是不允许泛型的。当您部分应用 function 时,结果是一个 value

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

您遇到的错误是 IEnumerable 不够具体,无法完全定义 。给定IEnumerable,您不知道要迭代什么,因此编译器无法确定该值的正确类型。

那么你的问题的答案如下:

    关键是值不能是通用的 添加类型定义让编译器知道这不是一个值,而是一个函数,或者是允许泛型的东西。

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

【讨论】:

以上是关于值限制 - 该值已被推断为具有泛型类型的主要内容,如果未能解决你的问题,请参考以下文章

泛型之泛型方法

C#泛型 类型约束

TS泛型类、泛型接口、泛型函数

013.泛型窗体常用属性

泛型类中的数组

请教一个unity有关于泛型参数的问题