最小函数中是否有错误?

时间:2018-04-06 05:22:48

标签: haskell

我有一个415920个数字的mins列表,全部应该关闭到0.1

Prelude Lib> take 5 mins
[9.83610706554002e-2,9.847021825032128e-2,9.847021825032128e-2,9.898395035483082e-2,9.898395035483082e-2]

然而:

Prelude Lib> minimum mins
0.10087849151477328

minimum函数不应该返回最小值?

这个结果听起来似乎有道理:

Prelude Lib> foldr min 100000 mins
1.1763616593045858e-4

这是一个错误,还是我误解了minimum

maximum的类似问题:

Prelude Lib> maximum mins
3261145.0627630088
Prelude Lib> foldr max 0 mins
0.1207868227600914

对列表进行排序会产生最大值的第三个结果:

Prelude Lib> import Data.List as L
Prelude Lib L> mins' = sort mins
Prelude Lib L> head mins'
1.1763616593045858e-4
Prelude Lib L> last mins'
0.10295664278431726

在排序列表中应用minimummaximum会产生最小值的第三个结果:

Prelude Lib L> minimum mins'
0.10045801977483232
Prelude Lib L> maximum mins'
3261145.0627630088

修改

在@ max630的评论之后,我用文本编辑器搜索了列表。 3261145.0627630088确实在这里,并且有一些NaN

NaN,NaN,3261145.0627630088

结论:看起来minimum会产生错误的结果,maximum会给出正确的结果。

foldr max给出错误的结果,foldl max给出了好的结果:

> foldl max 0 mins
3261145.0627630088

1 个答案:

答案 0 :(得分:14)

所有问题的原因是该列表包含NaN。显然它违反了Ord的总排序要求[*],所以你不能指望使用排序的算法 - 选择最小值或排序 - 在输入中产生正确的结果。相反,他们会产生一些取决于其内部实现的东西,并且可能根据看似不重要的原因(例如输入顺序)而有所不同。你应该在做其他任何事情之前将其过滤掉。

[*] Ord没有明确写出法律(NaN也会破坏Eq),但这里是破坏整体规则的例子,因为它是described in Wikipedia(感谢@sjakobi纠正):

Prelude> let nan = 0 / 0
Prelude> nan
NaN
Prelude> nan <= 1
False
Prelude> 1 <= nan
False
Prelude>