
On Wed, Sep 21, 2011 at 12:09 AM, Daniel Fischer
Yes. Which can be inconvenient if you are interested in whether you got a -0.0, so if that's the case, you can't simply use (== -0.0). Okay, problematic is a too strong word, but it's another case that may require special treatment.
Hmm. I was going to suggest that it's not a major concern so long as the distinction can't be observed without using functions specific to floating point values, since that preserves consistent behavior for polymorphic functions, but... that's not true, because the sign is preserved when dividing by zero! So we currently have the following behavior: 0 == (-0) = True 1/0 == 1/(-0) = False signum (-0) = 0.0 signum (1/0) = 1.0 signum (1/(-0)) = -1.0 All of which is, I believe, completely correct according to IEEE semantics, but seems to cause very awkward problems for any sensible semantics of Haskell's type classes. ...sigh.
which is correct and shouldn't break any expected behavior. I don't think it's required that distinguishable values be unequal,
But desirable, IMO.
I'm ambivalent. I can see it making sense for truly equivalent values, where there's a reasonable expectation that anything using them should give the same answer, or when there's a clearly-defined normal form that values may be reduced to. But as demonstrated above, this isn't the case with signed zeros if Num is available as well as Eq.
I still don't see why it makes sense to add separate IEEE comparisons
Pure and simple: speed. That is what the machine instructions, and hence the primops, deliver.
Oh, I assume the IEEE operations would be available no matter what, possibly as separate operations monomorphic to Float and Double, that they'd be used to define the partial ordering instance, and could be imported directly from some appropriate module. But as it turns out the partial ordering isn't valid anyway, so I retract this whole line of argument.
Ah, yes, wherein someone suggested that comparing to NaN should be a runtime error rather than give incorrect results. A strictly more correct approach, but not one I find satisfactory...
Umm, 'more correct' only in some sense. Definitely unsatisfactory.
More correct in the very narrow sense of producing fewer incorrect answers, according to Haskell semantics. :] That it would produce fewer answers in general and a great deal more bottoms is another matter. Certainly not useful, and in fact actively counterproductive given that the whole purpose of silent NaNs is to allow computations to proceed without handling exceptions at every step along the way. I'm becoming increasingly convinced that the only strictly coherent approach in the overall scheme of things would be to banish floating point values from most of the standard libraries except where they can be given correct implementations according to Haskell semantics, and instead provide a module (not re-exported by the Prelude) that gives operations using precise IEEE semantics and access to all the expected primops and such. As you said above, the importance of floating point values is for speed, and the IEEE semantics are designed to support that. So I'm happy to consider floats as purely a performance optimization that should only be used when number crunching is actually a bottleneck. Let Rational be the default fractional type instead and save everyone a bunch of headaches. - C.