Haskells背后的基本原理`succ`数字(浮点数)

时间:2015-03-04 14:06:48

标签: haskell floating-point enumerable

我有点惊讶地发现Haskell将数字上的succ函数定义为添加一个:

  

succ :: a -> a
  价值的继承者。对于数字类型,succ添加 1

虽然对于积分值,这似乎是合理的,但有一些问题:

  • 如果定义一个只能表示偶数/奇数/素数/ ...数字的数字系统,换句话说是一个专用类型,它是整数的一个子集,该怎么办;
  • 如果你定义某种代表半数和全数的“定点数”,那么不是所有的数字都是枚举的;和
  • 浮点数的问题最为严重。

首先,它意味着[2.0 :: Float .. 3.0 :: Float](使用:: Float来确保调用不含糊)仅包含添加到原始值的整数值,而如果使用此表达式他/她可能期望列表将包括两个值之间的所有浮点数;当然,这个论点更多的是人们喜欢什么。大多数程序员在这方面没有太多问题。

更严重的是,如果使用表达式[2.2 :: Float .. 4.0 :: Float],会导致[2.2,3.2,4.2] 4.2 在这里做什么?

如果使用浮点数,+1不能生成不同的数字(因为尾数没有足够的位来表示一个),它将无限循环。例如:

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.

因此,即使列表应为空或包含少量元素,也会产生无限量的值。

部分论据确实有点挑剔,但至少对某些人来说,假设Haskell程序员最终会犯错误是合理的。

生成下一个可表示的浮点数不是更合理的方法吗?

以这种方式定义succ的论据是什么? FloatEnum的实例是否合理?

1 个答案:

答案 0 :(得分:7)

succ函数本身的起源实际上与Haskell数据类型或枚举无关,事实上succ函数首先出现。 succ函数实际上是axiom of infinity中的 后继 函数,它允许我们create numbers in the first place。它从未被设计为与浮点数/非自然数一起使用,这就是您遇到此问题的原因。

在Haskell中修改浮点类型的succ函数可能是个好主意,你应该向邮件列表提交一些关于它的东西。虽然Haskell在Haskell98报告中是标准化的,但是不要对改变语言抱有希望。

如果您熟悉Haskell的类型类,则只需阅读以下内容:您提到了succ函数的不同可能用法,这就是它被定义为函数的原因对于Enum类型类。因此,您可以轻松地重新绑定它以使用newtype执行不同的操作。