STM和输出IO

nic*_*las 5 concurrency events haskell stm

如果我位于事务失败的 STM 内部,并且我作为正常控制流的一部分重试(无 STM 冲突等),我可能想向外部人员指示采取纠正措施的方法。

如果是纯粹‘传出’的话,那我的STM还是可以纯粹重放的。

我如何通过 STM 重试执行传出IO?

有人遇到过这种情况吗?这有多邪恶?

chi*_*chi 5

如果确定执行的IO不会影响STM的不变量,则可以使用 unsafeIOToSTM. 和所有东西一样,请小心使用它unsafe

然而,我确实想知道您是否真的需要它。从问题中无法判断。如果可以的话,你应该避免它。

  • @nicolas 使用 [`orElse`](https://hackage.haskell.org/package/stm-2.4.4.1/docs/Control-Monad-STM.html#v:orElse) 并返回成功/失败代码。``原子地 $ (myPossibilityFailingSTMAction >> return True) `orElse` (return False)``。如果你得到“False”,你就知道“myPossibilityFailingSTMAction”失败了。比“unsafeIOToSTM”干净得多 (5认同)
  • @nicolas我想我现在明白你的意思了——你想要STM的自动等待/重试功能,但你也想向用户报告重试的发生和情况。恐怕你的想法与 STM 的语义不(安全)兼容。这是一笔_交易_——整个交易要么成功发生,要么什么都没有发生。将 IO 放入事务中会破坏“或没有执行”部分。关于 STM 的 RWH 章节对“unsafeIOToSTM”何时适用有一些指导 (4认同)
  • @BenjaminHodgson我的理解是,要“要求用户采取纠正措施”,我们需要向用户报告问题。该问题在“重试”点已知,但该信息无法(轻松)逃脱 STM monad。非组合选项是“返回(左“原因”)”而不是重试,这需要使用不同的“orElse”来了解此约定。更糟糕的是,当返回错误时,我们可能_不_希望之前的写入生效。这非常棘手,而且我还不确定这种方法是否真的有效。 (2认同)