F# 逆向列表中的值限制问题

Rob*_*131 1 f#

由于值限制问题,以下 F# 代码无法编译:

let x = List.rev []
Run Code Online (Sandbox Code Playgroud)

但这编译:

let x = List.rev [] in 3::x
Run Code Online (Sandbox Code Playgroud)

据我了解,编译器推断它x必须是类型int list,因此它无法编译。

以下内容无法编译:

let x = List.rev [] in (3::x, true::x)
Run Code Online (Sandbox Code Playgroud)

但这确实:

let x = ([]) in (3::x, true::x)
Run Code Online (Sandbox Code Playgroud)

为什么?

bri*_*rns 5

据我了解*,在 F# 中声明值有两种方法:

  • 值有一个具体的类型(例如List<int>)。您必须显式指定此具体类型,或者编译器必须能够推断它。
  • 值具有通用类型(例如List<'t>)。您必须显式指定此泛型类型,或者编译器必须能够推断它并且该值必须是简单的不可变值。

考虑到这一点,以下是对您所看到的内容的解释:

// not allowed because x is generic, but not simple
let x = List.rev []

// allowed because the compiler can infer x's concrete type (List<int>)
let x = List.rev [] in 3::x

// not allowed because x is generic, but not simple
let x = List.rev [] in (3::x, true::x)

// allowed because x is both generic and simple (compiler can tell it's the empty list)
let x = ([]) in (3::x, true::x)
Run Code Online (Sandbox Code Playgroud)

* 值限制可能很棘手,因此我在解释中可能忽略了一些细微差别。