gpt4 book ai didi

Haskell STM 总是成功的

转载 作者:行者123 更新时间:2023-12-04 02:15:07 27 4
gpt4 key购买 nike

haskell 的 stm 库中有一个函数,其类型签名如下:

alwaysSucceeds :: STM a -> STM ()

根据我对 Haskell 中 STM 的了解,在执行 STM 计算时,有三种方式可能会“出错”(松散地使用该术语):
  • 已读取的 TVar 的值被另一个线程更改。
  • 违反了用户指定的不变量。这似乎通常是通过调用 retry 来触发的。让它重新开始。这有效地使线程阻塞,然后在读取集中的 TVar 更改后重试。
  • 抛出异常。调用throwSTM导致这个。这与前两个不同,因为事务不会重新启动。相反,错误被传播,或者使程序崩溃,或者被 IO monad 捕获。

  • 如果这些是准确的(如果不是,请告诉我),我无法理解 alwaysSucceeds可能会做。 always似乎建立在它之上的函数似乎可以在没有 alwaysSucceeds 的情况下编写作为:
    --This is probably wrong
    always :: STM Bool -> STM ()
    always stmBool = stmBool >>= check
    alwaysSucceeds 的文档说:

    alwaysSucceeds adds a new invariant that must be true when passed to alwaysSucceeds, at the end of the current transaction, and at the end of every subsequent transaction. If it fails at any of those points then the transaction violating it is aborted and the exception raised by the invariant is propagated.



    但由于参数的类型为 STM a ( a 中的多态性),它不能使用事务返回的值用于决策的任何部分。因此,它似乎会寻找我之前列出的不同类型的故障。但那有什么意义呢? STM monad 已经处理了失败。将它包装在这个函数中会如何影响它?以及为什么 a 类型的变量被丢弃,导致 STM () ?

    最佳答案

    alwaysSucceeds的特效不是它如何在运行时检查故障(单独运行“不变”操作应该做同样的事情),而是它如何在事务结束时重新运行不变检查。

    基本上,这个函数创建了一个用户指定的不变量,如上面的(2),它不仅现在必须保持,而且在以后的事务结束时也必须保持。

    请注意,“事务”并不是指 STM 中的每个子操作。 monad,而是传递给 atomically 的组合操作.

    我猜 a删除只是为了方便,因此您不必将操作转换为 STM () (例如使用 void ),然后将其传递给 alwaysSucceeds .无论如何,返回值对于以后的重复检查将毫无用处。

    关于Haskell STM 总是成功的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25705352/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com