Haskell 范围和浮点数 [英] Haskell ranges and floats
问题描述
为什么浮点数和整数和字符的 Haskell 范围表示法的行为不同?
Why is the behavior of the Haskell range notation different for floats than for integers and chars?
Prelude> [1, 3 .. 10] :: [Int]
[1,3,5,7,9]
Prelude> [1, 3 .. 10] :: [Float]
[1.0,3.0,5.0,7.0,9.0,11.0]
Prelude> ['a', 'c' .. 'f']
"ace"
如果最后一个元素接近上限我会理解,但这显然不是舍入问题.
I would understand it if the last element was close to the upper bound, but this is obviously not a rounding issue.
推荐答案
语法 [e1, e2 .. e3]
真的是 enumFromThenTo e1 e2 e3
的语法糖,它是 Enum
类型类中的一个函数.
The syntax [e1, e2 .. e3]
is really syntactic sugar for enumFromThenTo e1 e2 e3
, which is a function in the Enum
typeclass.
Haskell 标准 定义其语义如下:
对于 Int
和 Integer
类型,枚举函数具有以下含义:
For the types
Int
andInteger
, the enumeration functions have the following meaning:
- 序列
enumFrom e1
是列表[e1,e1 + 1,e1 + 2,…]
. - 序列
enumFromThen e1 e2
是列表[e1,e1 + i,e1 + 2i,…]
,其中增量i
是e2 - e1
.增量可能为零或消极的.如果增量为零,则所有列表元素都是一样. - 序列
enumFromTo e1 e3
是列表[e1,e1 + 1,e1 + 2,…e3]
.如果e1 > 则列表为空e3
. - 序列
enumFromThenTo e1 e2 e3
是列表[e1,e1 + i,e1 +2i,…e3]
,其中增量i
为e2 - e1
.如果增量是正数或零,列表在下一个元素为时终止大于e3
;如果e1 > 则列表为空e3代码>.如果增量是负数,当下一个元素小于时列表终止
e3
;如果e1 < 则列表为空e3
.
- The sequence
enumFrom e1
is the list[e1,e1 + 1,e1 + 2,…]
. - The sequence
enumFromThen e1 e2
is the list[e1,e1 + i,e1 + 2i,…]
, where the increment,i
, ise2 − e1
. The increment may be zero or negative. If the increment is zero, all the list elements are the same. - The sequence
enumFromTo e1 e3
is the list[e1,e1 + 1,e1 + 2,…e3]
. The list is empty ife1 > e3
. - The sequence
enumFromThenTo e1 e2 e3
is the list[e1,e1 + i,e1 + 2i,…e3]
, where the increment,i
, ise2 − e1
. If the increment is positive or zero, the list terminates when the next element would be greater thane3
; the list is empty ife1 > e3
. If the increment is negative, the list terminates when the next element would be less thane3
; the list is empty ife1 < e3
.
这几乎是您所期望的,但是 Float
和 Double
实例的定义不同:
This is pretty much what you'd expect, but the Float
and Double
instances are defined differently:
对于 Float
和 Double
,enumFrom
系列的语义由上述 Int
的规则给出, 除了当元素变得大于 e3 + i∕2
为正增量 i
或当它们变得小于 e3 + i∕2 时列表终止
表示否定的i
.
For
Float
andDouble
, the semantics of theenumFrom
family is given by the rules forInt
above, except that the list terminates when the elements become greater thane3 + i∕2
for positive incrementi
, or when they become less thane3 + i∕2
for negativei
.
我不太确定这样做的理由是什么,所以我可以给你的唯一答案是,它是这样的,因为它在标准中是这样定义的.
I'm not really sure what the justification for this is, so the only answer I can give you is that it is that way because it's defined that way in the standard.
您可以通过使用整数枚举并随后转换为 Float
来解决此问题.
You can work around this by enumerating using integers and converting to Float
afterward.
Prelude> map fromIntegral [1, 3 .. 10] :: [Float]
[1.0,3.0,5.0,7.0,9.0]
这篇关于Haskell 范围和浮点数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!