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

J F*_*sch 3 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)
Run Code Online (Sandbox Code Playgroud)

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

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

因为这显然没有伤害这个错误可以用某种方式用例如编译器选项来抑制,或者我需要捕获异常然后忽略它(这也可能花费额外的时间).

dan*_*anr 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)
Run Code Online (Sandbox Code Playgroud)

  • @JFritsch三重执行与其他实现相比如何?对于`retry`来说,它是非常有效的,因为在它读取的TVar之一被更改之前,不会再次尝试中止的事务.你可以通过更精细的'TVar'来恢复一些速度,这样"重试"就可以获得成功的机会获得更细粒度的信息. (2认同)

ram*_*ion 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)
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用[Control.Exception](http://www.haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Control-Exception)捕获运行时错误,例如模式匹配失败. html #v%3ADenormal),但是这个_will_使你的代码错误(因为执行顺序),难以维护,单一,并且它必须存在于`IO` monad中,因为你只能在那里捕获那些错误.使用这样的机器而不是简单地使用模式匹配是完全错误的:) (2认同)
  • 那个外循环'loopMyQ'看起来像一个忙碌的等待.你应该在第一个原子上进行测试和'重试'调用.然而,目前的TVar设计仍然感觉不对. (2认同)