键入推断创建不需要的约束

时间:2012-07-28 00:54:57

标签: f# type-inference

由于我需要花费大量时间来处理IDisposable,所以我设置了一次性用品列表和一个传递函数,以便添加项目作为副作用:

let mutable disposables = []
let (~-) (x:'a) = disposables <- x :: disposables; x

所以我希望能做到这一点:

let thing1 = -new Form()
let thing2 = -new Control()

for i in disposables do i.Dispose()

问题在于F#自动将'a约束为IDisposable,并显示警告消息:

  

此构造导致代码不像类型注释所指示的那样通用。类型变量'a已被约束为'IDisposable'类型。

那么operator ~-的返回类型就变成了IDisposable,这会破坏函数的便利性。

有没有办法阻止F#创建此约束?

2 个答案:

答案 0 :(得分:2)

知道了!

当我在函数中使用它而不是函数的类型签名时,答案是将x转发到IDisposable

let mutable disposables = []
let (~-) x = disposables <- (x :> IDisposable) :: disposables; x

答案 1 :(得分:1)

您没有要求就您的代码提出一般性建议,但我不得不指出一些奇怪的事情。

首先,你几乎不必打电话给Dispose()use是管理资源的标准方式。你可能应该这样做:

use thing1 = new Form()
use thing2 = new Control()

其次,为什么要为mutable变量分配不可变数据结构?如果您确信需要手动跟踪资源,请使用

let disposables = ResizeArray<IDisposable>()

最后,在定义一个在自己的范围之外变异变量的运算符之前,你应该考虑很久。这对于操作员来说是不寻常的行为(除非操作员的范围非常狭窄)。