【问题标题】:Is Haskell's STM `check` different from explicitly using `retry`?Haskell 的 STM `check` 与显式使用`retry` 不同吗?
【发布时间】:2015-06-25 02:42:15
【问题描述】:

我正在通过实现餐饮哲学家问题来试验 STM。

无论如何,我有以下定义。

data ChopStick = CS (TVar Bool)

takeChopstick :: ChopStick -> STM ()
takeChopstick (CS chopstick) = do
    isTaken <- readTVar chopstick
    check (isTaken)
    writeTVar chopstick True

这个函数被原子调用:

atomically $ do
    takeChopstick leftChopstick
    takeChopstick rightChopstick

当使用上述 takeChopstick 定义运行程序时,我体验到使用此定义运行它的不同结果:

takeChopstick :: ChopStick -> STM ()
takeChopstick (CS chopstick) = do
    isTaken <- readTVar chopstick
    if isTaken
        then retry
        else writeTVar chopstick True

尤其是程序挂起。

check(hackage, stm-2.2.0.1)的源码如下:

check :: Bool -> STM a
check b = if b then return undefined else retry

这似乎与我明确使用 retry 的效果相同。

check 与显式使用 retry 有何不同?是否将retry 调用进一步向下推,导致它重新启动不同的原子块?

【问题讨论】:

  • check 相比,您的then/else 已交换。
  • 天哪,这当然是显而易见的!谢谢@DanielWagner
  • @CodeMonkey 也许写下你自己对问题的答案并接受它,这样它就不会再打开了。
  • @PetrPudlák 好主意,我已经添加了自己的答案,但 2 天内无法接受。

标签: haskell stm


【解决方案1】:

不,check 与显式使用retry 没有什么不同,我只是将参数与check 混淆了。

解决方案是checkisTakenFalse,即check $ not isTaken

takeChopstick :: ChopStick -> STM ()
takeChopstick (CS chopstick) = do
    isTaken <- readTVar chopstick
    check (not isTaken)
    writeTVar chopstick True

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多