2011-12-28 17 views
0

最終的に、メッセージをキータプルとして格納する単純なメモリメッセージキューを実現したい。 {Dst-IP、Dst-Port {CreationTime、MessageList}}特定の宛先IPアドレスと宛先ポートの今後のすべてのメッセージをMessageListに追加する必要があります。Data.PSQueueとタイプが一致しない

私はData.PSQueue(またはおそらくData.Map)を呼び出すことを考えました。上記のDst-IPの例では、Dst-Portが鍵になる場合があり、CreationTimeが優先される可能性があります。 (実際のMessageListが何であるかはまだ分かりませんが、どういうわけか私は始めて見なければなりません)。

私はPSQから始めて、タイプの初期のハードルを克服することさえできません。私は以下のスニペットを変更する方法に応じて、私はすべてが

Couldn't match expected type `IO t0' 
       with actual type `PSQ.PSQ k0 p0 -> Maybe p0' 

または類似似ていること(ルックアップ機能付きまたは印刷機能付きのいずれか)様々なエラーが発生します。この初期の問題をどうやって解決できますか? Data.PSQueueよりも自分の要件に合ったものはありますか?

{-# LANGUAGE OverloadedStrings #-} 

import Control.Monad 
import Control.Monad.State.Strict 
import System.CPUTime 

import qualified Data.PSQueue as PSQ 
--import Language.Haskell.Pretty 

main = do 
    time <- getCPUTime 
    let q = PSQ.singleton "msg" time 
    r <- PSQ.lookup "msg" 
    print (r) 

答えて

4

r <- PSQ.lookup "msg"と書いてあります。 <-への構文で、はdo表記のブロック内のモナド値です。代わりにlet r = ...という構文を使用して、純粋な値をバインドする必要があります。

キューパラメータ自体も忘れています。 <-の右辺は、の場合はのタイプIO aである必要がありますが、PSQ k pから検索の結果(Maybe p)までの関数です。エラーメッセージが表示されます。

これらの2つの修正の後、修正された行はlet r = PSQ.lookup "msg" qです。

代わりに、State monadPSQを状態として使用します。例えばStateT PSQ IO。これは次のように、あなたのスニペットを書き直してみましょうになります。

main :: IO() 
main = flip runStateT PSQ.empty $ do 
    time <- liftIO getCPUTime 
    modify $ PSQ.insert "msg" time 
    r <- gets $ PSQ.lookup "msg" 
    liftIO . print $ r 

あなたが並行プログラムを書くことを意図している場合は、最善の解決策は、おそらく代わりにPSQを含むMVarTVarです。

fingertree-psqueueパッケージ、フィンガーツリーに基づく優先度の高い検索キューの実装に興味があるかもしれません。私はそれを使用していないか、あなたが検討しているPSQueueパッケージを使用していますが、より積極的に維持されているようです。

+0

ありがとうございました。単純なキーの代わりに質問テキストに記述されているように、キータプルを使用させる簡単な方法はありますか?たぶんレコードを使用するのでしょうか? –

+0

タプルやその他のデータ型(レコードなど)をキーとして使用できませんでしたか? – ehird

関連する問題