本文介绍了Haskell 范围和浮动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么 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 标准定义其语义如下:

对于 IntInteger 类型,枚举函数有以下含义:

  • 序列enumFrom e1 是列表[e1,e1 + 1,e1 + 2,…].
  • 序列 enumFromThen e1 e2 是列表 [e1,e1 + i,e1 + 2i,…],其中增量 ie2 − e1.增量可能为零或消极的.如果增量为零,则所有列表元素都是
  • 序列enumFromTo e1 e3 是列表[e1,e1 + 1,e1 + 2,…e3].如果 e1 >,则列表为空.e3.
  • 序列 enumFromThenTo e1 e2 e3 是列表 [e1,e1 + i,e1 +2i,...e3],其中增量 ie2 − e1.如果增量是正数或零,列表在下一个元素出现时终止大于 e3;如果 e1 >,则列表为空e3.如果增量是负数,当下一个元素小于时,列表终止e3;如果 e1 .
  • 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, is e2 − 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 if e1 > e3.
  • The sequence enumFromThenTo e1 e2 e3 is the list [e1,e1 + i,e1 + 2i,…e3], where the increment, i, is e2 − e1. If the increment is positive or zero, the list terminates when the next element would be greater than e3; the list is empty if e1 > e3. If the increment is negative, the list terminates when the next element would be less than e3; the list is empty if e1 < e3.

这与您所期望的差不多,但是 FloatDouble 实例的定义不同:

This is pretty much what you'd expect, but the Float and Double instances are defined differently:

对于FloatDoubleenumFrom 族的语义由上述Int 的规则给出,除了当元素变得大于 e3 + i∕2 对于正增量 i 时,或者当它们变得小于 e3 + i∕2 时,列表终止 表示否定 i.

我不确定这样做的理由是什么,所以我能给你的唯一答案是它是那样的,因为它在标准中是这样定义的.

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 范围和浮动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-19 11:12