F# 中 int 类型的 NaN 等价物是什么?

What is NaN equivalent for int type in F#?

在 F# 中,我可以像这样解析浮点数:

let tryParseFloat s =
    let ok,f = System.Double.TryParse s
    if ok then f else nan

然后

let parsed = tryParse "123.123"
match parsed with
| nan -> ignore parsed
| _ -> dostuff parsed

如何使用 int 实现类似的功能?

int 类似的类型没有 NaN 值。相反,您可以使用 int option。也许是这样的:

let tryParseInt s =
  let ok,i = System.Int32.TryParse s
  if ok then Some i else None

如果您想在 F# 中表示值的缺失,使用 option 是实现此目的的方法。这样做你可以通过类型系统非常清楚地知道值可能存在也可能不存在。所以你绝对应该在这里使用int option

出于同样的原因,我强烈建议您也使用 float option 而不是 NaN。

虽然 NaN 是 .NET 中浮点数的完全有效值,但它在 F# 类型系统中有点不足。特别是,nan = nan 为假,并且它不能很好地处理带有 NaN 的复杂 F# 类型(如可区分的联合和记录)的结构比较。您会遇到难以追踪的错误。虽然如果您作为数字运算的结果得到 NaN 是不可避免的,但您可以比使用它们来表示值的缺失做得更好。

因此请遵循@FuleSnabel 对 ints 的建议,并对 floats 使用类似这样的内容:

let tryParseFloat s =
    let ok, f = System.Double.TryParse s
    if ok then Some f else None

编辑:实际上,您发布的代码并不完全有效,部分原因是上述原因。

 match parsed with
 | nan -> ignore parsed
 | _ -> dostuff parsed

在这里您不检查 NaN,您将 parsed 绑定到一个名为 nan 的值,并且永远不会命中第二种情况 (warning FS0026: This rule will never be matched)。

稍微好一点的尝试是这样的:

 match parsed with
 | f when f = nan -> ignore parsed
 | _ -> dostuff parsed 

但是这里第一种情况永远不会被命中,因为正如我在上面写的那样,f 永远不会等于 nan(即使当parsed 是一个 NaN)

您需要使用 Double.IsNaN 检查 NaN:

 match parsed with
 | f when System.Double.IsNaN(f) -> ignore parsed
 | _ -> dostuff parsed 

但这只是表明这首先不是一个好主意。

tl;dr: NaN 对你不利。