Alaya
Alaya

Reputation: 3387

why does function enumFromThenTo behaves not same as it is defined in GHC.Enum?

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

Answers (1)

kosmikus
kosmikus

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

Related Questions