← Back to context

Comment by Mond_

2 hours ago

This is a bit confused. You're saying `float`, but a float comes with NaN by default. Any float can take NaN values.

If you actually want the compiler to check this on the level of the type system, it'd have to be `NonNaNFloat | NaN`. Then you can check which one you have and continue with a float that is guaranteed to not be NaN.

But (importantly) a NonNaNFloat is not the same as a float, and this distinction has to be encoded in the type system if you want to take this approach seriously. This distinction is NOT supported by most type systems (including Rust's std afaik, fwiw). It's similar to Rust's NonZero family of types.

Indeed this isn't anywhere in the Rust standard library, but there is `ordered_float::NotNan`: https://docs.rs/ordered-float/latest/ordered_float/struct.No... .

Unfortunately, Rust doesn't seem to be smart enough to represent `Option<NotNan<f64>>` in 8 bytes, even though in theory it should be possible (it does the analogous thing with `Option<NonZero<u64>>`).

This thread is discussing the possibility of adding such an optimization: https://internals.rust-lang.org/t/add-float-types-with-niche...