6

这个答案中,以下代码的评估如下:

> let x = fromList  [0, -1, 0/0, -5, -6, -3] :: Set Float

> member 0 x
True

> let x' = insert (0/0) x

> member 0 x'
False

作者指出发生这种情况是因为EqOrd浮点实例不遵守单子定律。EqOrd浮点实例如何打破单子定律,为什么会导致上述行为?

4

1 回答 1

14

违反的不是单子定律,而是Eq关于Ord.

定义等价关系的Eq按需定律,(==)

forall x. x == x
forall x y. x == y <=> y == x
forall x y z. x == y && y == z => x == z

并且合同Ord<定义总排序的,

forall x. not (x < x)
forall x y. (x < y) || (x == y) || (y < x)
forall x y. not (x < y && y < x)

浮点类型违反了这些定律,因为 NaN(NaN = Not a Number)与它们自身比较不相等,

0/0 /= 0/0

以及任何涉及 NaN 的比较<, , ... 返回。<=False

因此,当树中存在应该排序的 NaN 时,在搜索元素时与 NaN 进行比较可能会将递归搜索发送到错误的子树。

于 2013-04-01T15:45:52.853 回答