我有以下功能:
loopMyQ s q m = forever $ do
q' <- atomically $ readTVar q
let Just b = PSQ.findMin q' --irrefutable pattern here in case the queue has just been created
duetime = (PSQ.prio b) + 2.000
now <- getPOSIXTime
when (now > duetime) (transMit2 s now q m)
Run Code Online (Sandbox Code Playgroud)
问题是,当PSQ"刚刚"被创建为空PSQ时,Just无法匹配并在运行时给出了无可辩驳的模式错误.这恰好发生一次,因为显然队列后来被填充并且只是b总是匹配.
我试图测试队列是否为空,然后在我的函数中对它进行操作但是这使整个事情运行速度慢了两倍.
因为这显然没有伤害这个错误可以用某种方式用例如编译器选项来抑制,或者我需要捕获异常然后忽略它(这也可能花费额外的时间).
retry
如果队列为空,则可能最好使用:在更新STM队列之前,不会重试该操作TVar!
loopMyQ s q m = forever $ do
b <- atomically $ do q' <- readTVar q
case PSQ.findMin q' of
Just b -> return b
Nothing -> retry
let duetime = (PSQ.prio b) + 2.000
now <- getPOSIXTime
when (now > duetime) (transMit2 s now q m)
Run Code Online (Sandbox Code Playgroud)
假设,一旦你的队列是非空的,它永远不会再空,有一两件事你可以做的是做昂贵的版本(检查非空)只有等到它变成非空,然后切换到便宜的版本.
loopMyQ s q m = do
q' <- atomically $ readTVar q
case PSQ.findMin q' of
Nothing -> loopMyQ s q m
Just b -> do
body b
forever $ do
q' <- atomically $ readTVar q
let Just b <- PSQ.findMin q'
body b
where body b = do
let duetime = 2 + PSQ.prio b
now <- getPOSIXTime
when (now > duetime) (transMit2 s now q m)
Run Code Online (Sandbox Code Playgroud)