小编Max*_*son的帖子

为什么F#编译器有时会错误地推广函数?

我最近遇到了来自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!!!!
Run Code Online (Sandbox Code Playgroud)

为什么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
Run Code Online (Sandbox Code Playgroud)

但更神秘的是,根据这个定义,F#Interactive无法决定nextId是(obj - > int)还是('a - > int).当我第一次定义它时,我得到了

val nextId:(obj - > …

generics f# automatic-generalization

9
推荐指数
2
解决办法
181
查看次数

标签 统计

automatic-generalization ×1

f# ×1

generics ×1