[英]Rationale behind Haskells `succ` on numbers (floats)
I was a bit surprised to learn that Haskell defines its succ
function on numbers as adding one: 我有点惊讶地发现Haskell将数字
succ
函数定义为添加一个:
succ :: a -> a
The successor of a value.价值的继承者。 For numeric types, succ adds 1 .
对于数字类型,succ添加1 。
Although for integral values, this seems reasonable there are a few problems: 虽然对于整数值,这似乎是合理的,但有一些问题:
First of all, it means that [2.0 :: Float .. 3.0 :: Float]
(used :: Float
to make sure the call is not ambiguous) only contains integral values added to the original value, whereas if one uses this expression he/she might expect the list will include all floating points between the two values; 首先,它意味着
[2.0 :: Float .. 3.0 :: Float]
(使用:: Float
来确保调用不模糊)只包含添加到原始值的整数值,而如果使用这个表达式他/她可能希望列表中包含两个值之间的所有浮点数; of course this argument is more about what one prefers. 当然,这个论点更多的是人们喜欢什么。 Most programmers don't have much problems with this aspect.
大多数程序员在这方面没有太多问题。
More severely, if one uses the expression [2.2 :: Float .. 4.0 :: Float]
it results in [2.2,3.2,4.2]
what is 4.2
doing here? 更严重的是,如果使用表达式
[2.2 :: Float .. 4.0 :: Float]
它会导致[2.2,3.2,4.2]
4.2
在这里做什么?
If one uses a floating point number where +1
cannot generate a different number (because the mantissa doesn't have enough bits to represent one anymore), it will loop infinitely. 如果使用浮点数,其中
+1
不能生成不同的数字(因为尾数没有足够的位来代表一个),它将无限循环。 For instance: 例如:
Prelude> [1e37 :: Float .. 1e37 :: Float]
[1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,1^C.0e37,Interrupted.
Prelude> [1e37 :: Float .. 1e37-1 :: Float]
[1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,1^C.0e37,Interrupted.
Prelude> [1e37 :: Float .. 1e37+1 :: Float]
[1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,1^C.0e37,Interrupted.
Prelude> [1e37 :: Float .. pred 1e37 :: Float]
[1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,1^C.0e37,Interrupted.
One thus generates an infinite amount of values, even if the list ought to be empty or contain a few elements. 因此,即使列表应该为空或包含一些元素,也会产生无限量的值。
Part of the arguments are indeed a bit nitpicking, but at least for some, it is reasonable to assume that a Haskell programmer will eventually make mistakes. 部分论点确实有点挑剔,但至少对某些人来说,假设Haskell程序员最终会犯错误是合理的。
Wouldn't a more reasonable approach have been to generate the next representable floating point number? 生成下一个可表示的浮点数是不是更合理的方法?
What were the arguments to define succ
in such way? 以这种方式定义
succ
的论据是什么? Is it reasonable that Float
is an instance of Enum
? Float
是Enum
一个例子是否合理?
The origin of the succ
function itself actually has nothing to do with the Haskell data types or enumerations, in fact the succ
function came first. succ
函数本身的起源实际上与Haskell数据类型或枚举无关,实际上succ
函数首先出现。 The succ
function is actually the successor function in the axiom of infinity which allows us to create numbers in the first place . succ
函数实际上是无穷大公理中的后继函数,它允许我们首先创建数字 。 It was never designed to be used with floating point/non-natural numbers, that's why you're encountering this problem. 它从来没有设计用于浮点数/非自然数,这就是你遇到这个问题的原因。
It would probably be a good idea to modify the succ
function for floating point types in Haskell, you ought to submit something to the mailing list about it. 在Haskell中修改浮点类型的
succ
函数可能是个好主意,你应该向邮件列表提交一些关于它的东西。 Although, Haskell is standardized in the Haskell98 report so don't get your hopes up about changing the language. 虽然Haskell在Haskell98报告中是标准化的,所以不要对改变语言抱有希望。
Only read the following if you are familiar with Haskell's type classes: You mention different possible uses of the succ
function, this is why it is defined as a function for the Enum
type class. 如果您熟悉Haskell的类型类,请阅读以下内容:您提到了
succ
函数的不同可能用法,这就是为什么它被定义为Enum
类型类的函数。 Therefore you can easily rebind it to do something different with a newtype
. 因此,您可以轻松地重新绑定它以使用
newtype
执行不同的操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.