[Haskell-cafe] Exception for NaN

Casey McCann syntaxglitch at gmail.com
Mon May 16 20:51:56 CEST 2011

On Mon, May 16, 2011 at 3:39 AM, Ketil Malde <ketil at malde.org> wrote:
> I'm not intimately familiar with IEEE 754, but in any case we'd be in
> good company: R typically lets you select to sort NaNs as greater or
> less than any other values, and sorts non-NaN values correctly also in
> the presence of NaNs, I think.

That's interesting. I wasn't aware of any deliberate breaks with the
standard, and it being R specifically is particularly striking.
Regardless, sticking to the standard behavior is a sensible default.
Floating point values are confusing enough to most people without
being inconsistent as well.

> At any rate, I think we already violate the spec by not having the
> required "unordered" result for comparisons, and just treating every
> comparison involving a NaN as "GT".  I don't think considering NaN as
> e.g. less than -Inf would violate the spec *more*.

Well, it'd be insult to injury. If memory serves me, the standard
behavior is that NaN =/= NaN evaluates as true, and every other
comparison evaluates as false. This is fine (other than not being the
expected behavior of Eq and Ord instances) except, yes, the "compare"
function, which assumes a complete ordering and thus cannot return a
correct result. The slightly more correct thing to do would be having
"compare" throw an exception on NaN but I wonder if that wouldn't just
cause a different set of headaches.

Why don't we have a partial ordering type class, anyway? Lack of
obvious utility, I suppose.

> This sounds pretty bad, until you consider that you don't even have
> proper equality, so using floating point values as keys in a Map is
> already asking for trouble.  But I would like sorting to work more
> consistently.
> But I guess it is a matter of lipstick on a pig...

How so? Equality on floating point values other than NaN works just
fine and behaves as expected. It's just that they violate all sorts of
algebraic laws when arithmetic is involved so sequences of operations
that should be equivalent aren't, in ways that are highly dependent on
the values being operated on.

What it mostly boils down to is that Haskell makes you expect things
to be simple and consistent and clearly-defined and floating point
values just simply aren't. They're a messy compromise for the sake of
computational speed. If you want numbers that act like they should,
there's always Integer and Rational.

- C.

More information about the Haskell-Cafe mailing list