Rational sequence

Dean Herington heringto@cs.unc.edu
Thu, 24 Oct 2002 13:36:35 -0400


Simon Peyton-Jones wrote:

> Folks
>
> The concrete is setting fast, but Ross points out that the instance for
> Enum (Ratio a) is inconsistent with that for Enum Float and Enum Double.
> (It's strange that these non-integral types are in Enum, but we're stuck
> with that.)
>
> All three use 'numericEnumFrom' etc for the enumFrom method, but Float
> and Double define succ and pred thus:
>
>         instance Enum Float where
>                 succ x = x+1
>                 pred x = x-1
>
> But Ratio does not... it uses the default method for succ/pred which
> gives
>
>         instance Integral a => Enum (Ratio a) where
>                 succ x = fromInt (1 + (toInt x))
>
> Thus (succ (1.5 :: Float)) is 2.5
> but   (succ (3%2)) is 2%1
>
> Furthermore, you'd expect that
>         [x..y]
> would mean the same as
>         [x,succ x .. y]
> and that is true for Float/Double but not for Ratio.
>
> So I propose to modify the instance decl for Ratio by adding explicit
> defns for succ/pred just like those in Float/Double.
>
> Any objections?
>
> Simon

No objection, but here are additional related corrections to be made:

(1) In section A (Standard Prelude), in the definition of
`numericEnumFromThenTo`, change "n' > n" to "n' >= n", to agree with the
last bullet in section 6.3.4.  That is, the function definition should read:

numericEnumFromThenTo n n' m = takeWhile p (numericEnumFromThen n n')
                             where
                               p | n' >= n   = (<= m + (n'-n)/2)
                                 | otherwise = (>= m + (n'-n)/2)

(2) In section 3.10, change "which Prelude type are in Enum" to "which
Prelude types are in Enum".

 -- Dean