为什么函数enumFromThenTo的行为与GHC.Enum中定义的行为不同?

Ala*_*aya 1 haskell ghc

这里了解到,功能的定义enumFromThenTo

enumFromThenTo      :: a -> a -> a -> [a]
enumFromThenTo x1 x2 y = map toEnum [fromEnum x1, fromEnum x2 .. fromEnum y]
Run Code Online (Sandbox Code Playgroud)

但是,当我用下面的代码测试函数时:

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]
Run Code Online (Sandbox Code Playgroud)

价值xs1[1.0,3.0,5.0,7.0,9.0]同时的值xs2[1.0,3.0,5.0,7.0,9.0,11.0]

为什么会这样?

kos*_*kus 5

您使用的定义只是类中的默认定义.个别实例可以自由使用不同的定义.实际上,实际实例Enum Double被定义GHC.Float并使用不同的定义.

从源文件复制相关注释:

Floats和Doubles的@ Enum @实例略有不同寻常.@toEnum @函数将数字截断为Int.@ enumFrom @和@ enumFromThen @的定义允许浮点数用于算术系列:[0,0.1 .. 1.0].然而,舍入错误使这些有点可疑.此示例可能包含10个或11个元素,具体取决于0.1的表示方式.注意:Float和Double的实例不使用@ enumFromTo @和@ enumFromThenTo @的默认方法,因为它们依赖于Int的"无损"转换.相反,我们使用1.2默认方法(在Enum将Ord作为超类的时代)(@ numericEnumFromTo @和@ numericEnumFromThenTo @下面).