Reputation: 3387
Learnt from here, the definition of function enumFromThenTo
is
enumFromThenTo :: a -> a -> a -> [a]
enumFromThenTo x1 x2 y = map toEnum [fromEnum x1, fromEnum x2 .. fromEnum y]
However, when I tested the function with code below:
import GHC.Enum
myEnumFromThenTo :: Enum a => a->a->a->[a]
myEnumFromThenTo x1 x2 y = map toEnum [fromEnum x1, fromEnum x2 .. fromEnum y]
xs1 :: [Float]
xs1 = myEnumFromThenTo 1 3 10
xs2 :: [Float]
xs2 = enumFromThenTo 1 3 10
-- -- | Used in Haskell's translation of @[n,n'..m]@.
-- enumFromThenTo :: a -> a -> a -> [a]
The value of xs1
is [1.0,3.0,5.0,7.0,9.0]
while the value of xs2
is [1.0,3.0,5.0,7.0,9.0,11.0]
Why would it be so?
Upvotes: 1
Views: 607
Reputation: 19637
The definition you use is just the default definition from the class Individual instances are free to use different definitions. Indeed, the actual instance Enum Double
is defined in GHC.Float
and makes use of a different definition.
Copying the relevant comment from the source file:
The @Enum@ instances for Floats and Doubles are slightly unusual. The @toEnum@ function truncates numbers to Int. The definitions of @enumFrom@ and @enumFromThen@ allow floats to be used in arithmetic series: [0,0.1 .. 1.0]. However, roundoff errors make these somewhat dubious. This example may have either 10 or 11 elements, depending on how 0.1 is represented. NOTE: The instances for Float and Double do not make use of the default methods for @enumFromTo@ and @enumFromThenTo@, as these rely on there being a `non-lossy' conversion to and from Ints. Instead we make use of the 1.2 default methods (back in the days when Enum had Ord as a superclass) for these (@numericEnumFromTo@ and @numericEnumFromThenTo@ below.)
Upvotes: 5