哈斯克尔范围和浮游物 [英] Haskell ranges and floats

查看:182
本文介绍了哈斯克尔范围和浮游物的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么Haskell范围表示法对于浮点数比整数和字符有所不同?

  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

我会理解,如果最后一个元素接近上限,但这显然不是一个四舍五入的问题。

解决方案

语法 [e1,e2 .. e3] 真的是 enumFromThenTo e1 e2 e3 的语法糖, Enum typeclass。



Haskell标准定义了它的语义如下:


<对于类型 Int Integer ,枚举函数具有
的含义:




  • 序列 enumFrom e1 是列表 [e1,e1 + 1,e1 + 2,...]

  • 序列 enumFromThen e1 e2 c $ c> [e1,e1 + i,e1 + 2i,...] ,
    其中incr 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


Float Double 实例的定义是不同的:


对于 Float Double enumFrom的语义系列由上面的 Int 的规则给出,只是当元素大于 e3 + i / 2 为正增量 i 或者小于 e3 + i / 2 为负面


我不太确定是什么理由因此,我可以给你的唯一答案就是这样,因为它是在标准中定义的。



你可以通过枚举来解决这个问题整数,然后转换为 Float

  Prelude> map fromIntegral [1,3..10] :: [Float] 
[1.0,3.0,5.0,7.0,9.0]


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.

解决方案

The syntax [e1, e2 .. e3] is really syntactic sugar for enumFromThenTo e1 e2 e3, which is a function in the Enum typeclass.

The Haskell standard defines its semantics as follows:

For the types Int and Integer, the enumeration functions have the following meaning:

  • 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.

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

For Float and Double, the semantics of the enumFrom family is given by the rules for Int above, except that the list terminates when the elements become greater than e3 + i∕2 for positive increment i, or when they become less than e3 + i∕2 for negative 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.

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]

这篇关于哈斯克尔范围和浮游物的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆