我最近遇到了 F# 编译器的一些意外行为。我能够找到一种解决方法,但最初的行为让我感到困惑,我想看看是否有人可以帮助我了解导致它的原因。
我定义为非泛型的函数正在变为泛型,这干扰了函数在多个调用之间共享状态的能力。我将我的用例简化为以下内容:
let nextId =
let mutable i = 0
let help (key:obj) =
i <- i + 1
i
help
nextId "a" // returns 1
nextId "b" // also returns 1!!!!
为什么nextId类型为 'a -> int 而不是 obj -> int?显然,泛化也是导致它重复返回 1 的错误的原因,但是为什么泛化首先会发生呢?
请注意,如果我在没有命名嵌套函数的情况下定义它,它会在提供唯一 ID 时按预期工作:
let nextId =
let mutable i = 0
fun (key:obj) ->
i <- i + 1
i
nextId "a" // returns 1
nextId "b" // returns 2
但更神秘的是,有了这个定义,F# Interactive 无法判断 nextId 是 (obj -> int) 还是 ('a -> int)。当我第一次定义它时,我得到
val nextId : (obj -> int)
但如果我只是评估
nextId
我明白了
验证它:('a -> int)
这里发生了什么,为什么我的简单函数会自动泛化?