# [Haskell-cafe] instance Enum Double considered not entirely great?

Casey McCann cam at uptoisomorphism.net
Wed Sep 21 20:39:09 CEST 2011

```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

...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
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