简体   繁体   中英

What is NaN equivalent for int type in F#?

In F# I can parse a float like this:

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

and then

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

How can I achieve similar functionality with int?

int like types doesn't have a NaN value. Instead you can use int option . Maybe something like this:

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

If you want to represent an absence of a value in F#, using option is the way to do it. Doing that you make it abundantly clear through the type system that the value may or may not be there. So you should definitely use int option here.

I would strongly advise you to use a float option as well, instead of a NaN, for the same reason.

While NaN is a perfectly valid value for a float in .NET, it's sort of a dent in F# type system. In particular, nan = nan is false, and it doesn't play well with structural comparisons for complex F# types (like discriminated unions and records) that carry NaNs. You get errors that can be painful to track down. While it can be unavoidable if you get NaN's as result of numeric operations, you can do better than using them to represent absence of a value as well.

So follow @FuleSnabel's advice for ints , and use something like this for floats :

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

Edit: Actually, the code you posted doesn't quite work, in part because of the above.

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

Here you don't check for a NaN, you bind parsed to a value called nan , and the second case will never be hit ( warning FS0026: This rule will never be matched ).

A slightly better attempt would be something like this:

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

But here the first case will never be hit, because as I just wrote above, f will never be equal to nan (even when parsed is a NaN )

You need to use Double.IsNaN to check for NaNs:

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

But it just shows that it wasn't a good idea in the first place.

tl;dr: NaNs are bad for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM