一千萬個為什麽

搜索

輸入與Data.PSQueue不匹配

最終我想實現一個簡單的內存消息隊列,它將消息存儲為關鍵元組,例如{Dst-IP,Dst-Port {CreationTime,MessageList}}其中特定目標IP地址和目標端口的所有未來消息都應附加到MessageList。

我考慮過調查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)

最佳答案

You've written r <- PSQ.lookup "msg". <- is the syntax to extract a monadic value from within a block of do-notation. You should instead use let r = ..., the syntax to bind pure values.

You also forgot the queue parameter itself. This is what the error message is telling you: the right-hand side of <- has to be of type IO a for some a, but instead it's a function from a PSQ k p to the result of a lookup (Maybe p).

在這兩個修復之後,更正的行是 let r = PSQ.lookup“msg”q

也許您想要的是狀態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

如果您打算編寫並發程序,最好的解決方案可能是包含 PSQMVarTVar

您可能還對 fingertree-psqueue 包感興趣,該包是基於優先級搜索隊列的實現在手指樹上。我沒有使用它或你正在考慮的 PSQueue 軟件包,但似乎更多積極維護。

轉載註明原文: 輸入與Data.PSQueue不匹配