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

时间:2016-02-02 21:04:09

标签: .net f# int tryparse

在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实现类似的功能?

2 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:4)

如果您想在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(即使parsedNaN

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

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

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

tl; dr: NaN对你不利。