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

Jake McArthur jake.mcarthur at gmail.com
Wed Sep 21 13:42:02 CEST 2011

```On Tue, Sep 20, 2011 at 11:29 PM, Richard O'Keefe <ok at cs.otago.ac.nz> wrote:
>
> On 21/09/2011, at 2:59 AM, Chris Smith wrote:
>
>> On Mon, 2011-09-19 at 22:09 -0700, Evan Laforge wrote:
>>> Then I tried switching to a fixed point format, and discovered my
>>> mistake.  Enum is supposed to enumerate every value between the two
>>> points, and the result is memory exhaustion.
>
> % ghci
> Prelude> [1.0..2.0]::[Double]
> [1.0,2.0]
>
> (..) for Doubles is using (+1), not nextAfter, and is NOT enumerating
> every value between 1.0 and 2.0
>
>> import Ratio
> Prelude Ratio> [1%2..7%2] :: [Ratio Int]
> [1 % 2,3 % 2,5 % 2,7 % 2]
>
> (..) for (Ratio a) is using (+1), and is NOT enumerating the infinitely
> many values between 1.5 and 3.5.
>
> Why should your fixed point format behave any differently?

Evan's claim was that Double and Ratio are doing the incorrect thing;
the evidence you gave may support your point, but it supports his as
well.

My claim now, and I think Evan agrees although I am not sure, is that
Double and Ratio shouldn't be instances of Enum at all, since
enumerating (a simulation of) the reals and enumerating the rationals
in order is nonsensical. I also find that toEnum . fromEnum /= id
annoying; anything that relies on it, like EnumSet/EnumMap [1], goes
down the toilet. Other things I think are reasonable to expect are
also broken; for example, toEnum . succ . fromEnum /= succ (granted,
it is reasonable to expect this to be broken considering that toEnum .

With fixed point numbers, it makes sense to have an Enum instance.
Enumeration is reasonable because most applications for fixed point
arithmetic do *not* want to pretend that they are real numbers; you
almost always want to be aware of the current precision and whether
you might overflow or need more precision. This situation is no
different from Word or Int. toEnum and fromEnum are also inverses. No
expectations are violated here unless you have already gotten used to
the broken Float, Double, and Rational instances.

- Jake