在 Haskell 中,[0.1..1] 返回 [0.1,1.1]。为什么?

ren*_*enW 6 haskell list

[0.1..1]我发现Haskell 将返回该列表,但我不明白为什么会这样[0.1,1.1]。谁能给我解释一下吗?

chi*_*chi 10

TL;DR:不要用于[x..y]浮点数。你可能会得到意想不到的结果。

对于浮点数, 没有合理的语义[x..y]。例如,有人可能会认为语义应该是该形式的最大值[x,x+1,x+2,...,x+n]是。但是,这并没有考虑浮点舍入误差。可能会产生比精确值稍大的值,从而使列表比预期短。因此,这种语义使得 的值变得相当不可预测。x+n<=yx+nylength [x..y]

Haskell 试图通过允许最大错误来缓解这个问题0.5。基本原理如下:当比 更x+n接近时,应将其视为区间中的某个值,并四舍五入到更大的值。有争议,但这就是 Haskell 的工作原理。yy+1[x..y]

在类似于显式步进的枚举中[x,y .. z](例如[0.0,5.0 .. 1000.0]),Haskell 相反允许错误(y-x)/22.5在示例中)。基本原理是相同的:我们包含那些比1000更接近的点1000+5

你可以在Haskell 报告中找到所有血淋淋的细节,它定义了 Haskell 的语义。这部分也是相关的。

Haskellers 普遍认为这是语言中的一个小缺陷。有些人认为我们不应该强制执行Enum FloatEnum Double[1.0 .. 5.0]删除这些实例将有效地阻止类似或更糟糕的麻烦情况[1.0 .. 5.5](这在数值上又不稳定)。