给出以下定义
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# 编译器)
引发了一个错误,但已关闭并显示以下响应
是的,这是设计使然 - IEnumerable 在字符串所在的地方没有密封,并且 这会导致触发值限制
解决方法是添加类型注释
let fn (id: int) (_:IEnumerable ) = id
let fnPartial<'a> = fn 1
有人可以解释一下吗
- 问题的症结是什么
- 添加类型注释如何解决问题
关键是 F# 中不允许值是泛型的。部分应用函数时,结果是一个值。
为了使绑定(或赋值)的左侧成为函数,必须在左侧定义一个参数。
您收到的错误是由于IEnumerable
不够具体而无法完全定义值的结果。给定IEnumerable
您不知道要迭代的内容,因此编译器无法确定值的正确类型。
那么,您的问题的答案如下:
- 关键是问题在于值不能是泛型 的
- 添加类型定义可以让编译器知道这不是一个值,而是一个函数,或者允许泛型的东西。
以下是相关的 MSDN 文档: https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/dd233183(v=vs.100)#value-restriction