我目前正在尝试使用hackage使用heap-1.0.0软件包的一些代码使用deepseq来确保完全严格评估计算。
我发现要使用deepseq我需要为较大表达式中涉及的类型声明NFData实例。到目前为止都很好。然后我到达Data.Heap,我用它来保存一些项目的优先级队列。突然不太好。
基本上,就我所知,我无法使deepseq和heap一起工作,因为堆的数据构造函数被隐藏起来,并且NFData实例不会在堆库本身内声明。
我的理解是否正确?是否有任何已知的方法可以使这些库协同工作并实现互操作?
提前致谢!
答案 0 :(得分:2)
没有必要深入了解堆。 HeapT类型定义为
data HeapT prio val
= Empty -- ^ An empty 'HeapT'.
| Tree { _rank :: {-# UNPACK #-} !Int -- ^ Rank of the leftist heap.
, _size :: {-# UNPACK #-} !Int -- ^ Number of elements in the heap.
, _priority :: !prio -- ^ Priority of the entry.
, _value :: val -- ^ Value of the entry.
, _left :: !(HeapT prio val) -- ^ Left subtree.
, _right :: !(HeapT prio val) -- ^ Right subtree.
} -- ^ A tree node of a non-empty 'HeapT'.
deriving (Typeable)
如果您只使用普通seq
,它会将堆评估为弱头正常形式,即Empty
或Tree
构造函数。由于size字段是严格的,因此将完全评估堆的主干。
如果您在输入新项目时将其与deepseq
结合使用,则将对堆进行全面评估。
let insert' item heap = item `deepseq` Data.Heap.insert item heap
let newheap = insert' item heap
in newheap `seq` do_something_else
话虽如此,如果这会导致性能下降,我不会感到惊讶。由于堆包使用Okasaki的实现,它依赖于懒惰以获得某些性能保证。试试吧,看看。
答案 1 :(得分:1)
instance NFData Heap where
rnf x = rnf (toUnsortedList x) `seq` ()
不是最有效率的,但是通常不会发现所有内容: - )