类型与Data.PSQueue不匹配 [英] Type mismatch with Data.PSQueue

查看:163
本文介绍了类型与Data.PSQueue不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最终,我想实现一个简单的内存消息队列,它将消息存储为密钥元组,例如{Dst-IP,Dst-Port {CreationTime,MessageList}}特定目标IP地址和目标端口的所有未来消息应附加到MessageList中。

关于Data.PSQueue的调查(或者Data.Map)。在上面的Dst-IP示例中,Dst-Port可能是关键,而CreationTime可能是重点。 (我不知道实际的MessageList可能是什么,但不知何故,我必须开始看到)。



从PSQ开始,我甚至没有超过最初的障碍类型。根据我如何修改下面的代码片段,我得到了各种类似的错误(无论是查找函数还是打印函数),都与

 无法匹配预期类型`IO t0'
,其实际类型为`PSQ.PSQ k0 p0 - >也许p0'

或类似。我怎样才能克服这个最初的问题?
有什么比Data.PSQueue更适合我的需求吗?

  { - #LANGUAGE OverloadedStrings# - } 

导入Control.Monad
导入Control.Monad.State.Strict
导入System.CPUTime

导入限定的Data.PSQueue作为PSQ
--import Language.Haskell.Pretty

main = do
time< - getCPUTime
let q = PSQ.singletonmsgtime
r< - PSQ .lookupmsg
print(r)


解决方案

你已经写了 r < - PSQ.lookupmsg< - 是从注释块中提取一次值的语法。您应该使用 let r = ... ,这是绑定纯数值的语法。



您也忘记了队列参数本身。这就是错误信息告诉你的:< - 的右边必须是 IO a 对于某些 a ,但是它是一个从 PSQ kp 到查找结果( Maybe p )。



在这两个修正后,修正的行是 let r = PSQ.lookupmsgq



也许你想要的是 State monad 作为状态的 PSQ 例如 StateT PSQ IO 。这可以让你重写你的代码片段,如下所示:

  main :: IO()
main = flip runStateT PSQ。 empty $ do
time< - liftIO getCPUTime
modify $ PSQ.insertmsgtime
r< - gets $ PSQ.lookupmsg
liftIO。打印$ r

如果您打算编写并发程序,最好的解决方案可能是 MVar 包含 PSQ 的TVAR



您可能也对 fingertree-psqueue a>包,基于手指树的优先搜索队列的实现。我没有使用它或您正在考虑的 PSQueue 软件包,但它似乎更多积极维护。

Eventually I want to achieve a simple in memory message queue that stores messages as key-tuples e.g. {Dst-IP, Dst-Port {CreationTime, MessageList}} where all future messages for a specific Destinations IP address and Destination Port should be appended to MessageList.

I thought about invetigating Data.PSQueue (or maybe Data.Map). In the example above the Dst-IP, Dst-Port could be the key whilst CreationTime could be the priority. (I have no idea yet what the actual MessageList could be, but somehow I have to start and see).

Starting with PSQs I do not even get past the initial hurdle of types. Depending on how I modify the below snippet, I get various errors (either with the lookup function or with the print function) that all resemble

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

or similar. How can I get past this initial problem? Is there anything that fits my requirements better than 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).

After those two fixes, the corrected line is let r = PSQ.lookup "msg" q.

Perhaps what you instead want is a State monad with a PSQ as the state; e.g. StateT PSQ IO. This would let you rewrite your snippet as follows:

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

If you're intending to write a concurrent program, the best solution is probably an MVar or TVar containing a PSQ instead.

You might also be interested in the fingertree-psqueue package, an implementation of priority search queues based on finger trees. I haven't used it or the PSQueue package you're considering, but it seems to be more actively maintained.

这篇关于类型与Data.PSQueue不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆