抑制运行时错误“模式Data.Maybe.Just b”的Irrefutable模式失败

时间:2012-03-13 01:06:30

标签: haskell

我有以下功能:

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)

问题是,当PSQ“刚刚”被创建为空PSQ时,Just无法匹配并在运行时给出了无可辩驳的模式错误。这恰好发生一次,因为显然队列后来被填满而且只是b总是匹配。

我试图测试队列是否为空,然后在我的函数中对它进行操作但是这使整个事情的运行速度慢了两倍。

由于这显然没有伤害,因此可以通过例如某种方式抑制此错误。编译器选项或者我是否需要捕获异常然后忽略它(这也可能需要额外的时间)。

2 个答案:

答案 0 :(得分:9)

使用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)

答案 1 :(得分:5)

假设一旦你的队列非空,它永远不会再空了,你可以做的一件事就是做昂贵的版本(检查非空),直到它变为非空,然后切换到便宜版本

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)