我偶然发现了一些我猜测是Data.Map
中的错误的东西,但这也很可能是我的Haskell知识中的错误。希望有人能澄清它是什么:)
请参考this gist。我正在将循环链表结构序列化为字节流。对于任何给定节点,格式为:
data Node = Node
{ val :: Word8
, next :: Node
}
我希望它被序列化为一对字节:第一个字节表示val
,第二个字节表示字节流中可以找到next
的偏移量。例如,我希望:
let n0 = Node 0 n1
n1 = Node 1 n0
被序列化为[0, 1, 1, 0]
。没什么大不了的。
这里有点棘手的部分是我正在利用MonadFix
RWST
实例来“绑定”字节流偏移:我维护一个从节点到偏移的地图,在此期间填充地图序列化,但也引用了映射中的条目,这些条目在序列化完成之前不一定存在。
当地图实施为Data.HashMap.Lazy
(来自unordered-containers)时,此功能非常有用。但是,当实现是通常的Data.Map
(来自containers)时,程序堆栈溢出 - 没有双关语意图 - Map
无限尝试使用{{1来比较两个节点}}
所以我的问题是:这是(==)
中的错误,还是我假设这些结构在Data.Map
存在错误的情况下应该如何表现?
答案 0 :(得分:22)
您的Ord
实例不起作用:
instance Ord Node where -- for use in Data.Map
Node a _ < Node b _ = a < b
对于有效的Ord
实例,您必须定义compare
或(<=)
。如果您只定义(<)
,则对compare
或(<=)
的任何调用都将无限循环,因为两者都有默认的实现方式。 Ord
的其他成员也是根据compare
定义的,因此除了(<)
之外什么都不会有效。