【问题标题】:Irrefutable pattern inside an action?动作中无可辩驳的模式?
【发布时间】:2012-03-18 09:39:16
【问题描述】:

在我的应用程序中,多个线程修改相同的数据。虽然在“正常”情况下总会有一条消息,但我发现在处理大量数据时,可能会发生另一个线程更快并在loopAction 运行之前删除messages

transMit :: Socket -> POSIXTime -> String -> TPSQ -> TMap -> IO ()
transMit s time newmsgs q m = do
     loopAction <- atomically $ do
                       mT <- readTVar m
                       qT <- readTVar q
                       let mT' = Map.delete key mT
                       let qT' = PSQ.delete key qT
                       writeTVar q (PSQ.insert key time qT')
                       writeTVar m (Map.insert key [newmsgs] mT')
                       return (let Just messages = Map.lookup key mT in sendq s (B.pack $ unwords messages) "192.168.35.84" 4711)
     loopAction

我在这里尝试了一个 case 表达式,例如

case (Map.lookup key MT) of
                           Nothing -> return ()
                           _ -> something w IO

但它当然不起作用,因为一个返回()而另一个分支返回 IO()等。我最好的解决方法是什么?

【问题讨论】:

  • 顺便说一句,do {m &lt;- mm; m} ≡ join mm,所以你可以写join . atomically $ do ...

标签: haskell


【解决方案1】:

这应该可以修复类型错误:

return $ case Map.lookup key mT of
              Nothing -> return ()
              Just messages -> sendq s (B.pack $ unwords messages) "192.168.35.84" 4711

这样,两个分支都会产生一个IO (),从而产生一个STM (IO ()) 整体。

但我不确定在价值观方面发生了什么。 mT 肯定不能被其他线程修改...

【讨论】:

  • @JFritsch 抱歉,在看到您的评论之前,我已添加到我的答案中。我的答案是否还有一部分解释得不够清楚?哪一部分?
猜你喜欢
  • 2013-01-18
  • 2012-10-22
  • 1970-01-01
  • 2015-12-25
  • 2011-10-29
  • 2018-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多