1

给出以下定义

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# 编译器)

提出了一个错误,但以以下响应关闭

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

解决方法是添加类型注释

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

有人可以解释

  1. 问题的症结是什么
  2. 添加类型注释如何解决问题
4

1 回答 1

2

关键是在 F# 中不允许值是通用的。当您部分应用一个函数时,结果是一个

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

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

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

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

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

于 2019-04-13T03:59:37.687 回答