2011-09-08 12 views
1

現在、ハックの使用deepseqからヒープ1.0.0パッケージを使用して計算を完全に厳密に評価するいくつかのコードを作成しようとしています。ハスケープヒープとdeepseqライブラリの互換性

deepseqを使用するには、より大きな式に関連する型のNFDataインスタンスを宣言する必要があることがわかりました。これまでのすべての良い。それから、私はData.Heapに行き、いくつかの項目の優先順位キューを保持するために使用します。突然良くない。

本質的に、私が知る限り、ヒープのデータコンストラクタは隠されており、NFDataインスタンスはヒープライブラリ自体の内部で宣言されていないため、deepseqとヒープを一緒に使用することはできません。

私の理解は正しいですか?これらのライブラリを連携させて相互運用させる方法はありますか?

ありがとうございます!

+3

メンテナをポーリングして必要なインスタンスを追加する方法はありますか? – fuz

答えて

1
instance NFData Heap where 
     rnf x = rnf (toUnsortedList x) `seq`() 

は、最も効率的な、しかし、その後、ウィリーnillyすべてをrnfingは、通常、ヒープをdeepseqする必要はありません:-)

2

ではありません。あなただけの通常のseqを使用する場合は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) 

として定義され、それが弱いヘッド正規形、すなわちいずれかEmptyまたはTreeコンストラクタにヒープを評価します。サイズフィールドは厳密なので、ヒープの背骨を完全に評価します。

これを入力するときに新しい項目をdeepseqと組み合わせると、ヒープが完全に評価されます。

let insert' item heap = item `deepseq` Data.Heap.insert item heap 

let newheap = insert' item heap 
in newheap `seq` do_something_else 

これは、パフォーマンスが悪化する場合は驚くことではありません。ヒープパッケージは岡崎の実装を使用しているため、特定のパフォーマンス保証のために怠惰に依存しています。それを試してみてください。

+0

私の理解は、岡崎の怠惰テクニックは、主にサンクの後ろのツリーバランスのようなハウスキーピング活動を隠すことであり、永続的な構造に同じ*リニア*バージョンの償却されたパフォーマンス特性を与えることです。したがって、ヒープ全体が完全にシーケンシャルな方法で使用されている場合、有益な*怠惰*ではなく単に無駄な*遅延があります。 :] –

+0

rnfingのアイデアは、あなたが実際にあなたが遅れて使う怠惰なデータ構造を持っている傾向があるということです。そして、今はいつでも、それは1つまたは別の理由で完全に評価されていることを強制します(おそらく、特別な機能に渡す前に例外がないことを保証するために、あるいはそれが表す「働き」が前にそれはワーカースレッドからメインスレッドに戻されます) - データ構造を使用すると、厳密には一般的に全く異なる問題です。 – sclv

+0

私はちょうどここで間違っているように思えます。さらなる調査の後、それは私の問題が他の場所にあるように見えます。ヒープの必要性deepseqは赤ちゃんでした。返事をありがとう - これは本当に私の理解に役立ちます! :-) –

関連する問題