繁体   English   中英

Haskell STM alwaysSucceeds

[英]Haskell STM alwaysSucceeds

haskell的stm库中有一个带有以下类型签名的函数:

alwaysSucceeds :: STM a -> STM ()

根据我对haskell中STM的理解,有三种方法可以在STM计算执行时出现“出错”(使用该术语):

  1. 已读取的TVar的值由另一个线程更改。
  2. 违反了用户指定的不变量。 这似乎通常是通过调用retryretry启动它来触发的。 这有效地使线程阻塞,然后一旦读取集中的TVar改变就重试。
  3. 抛出异常。 调用throwSTM会导致这种情况。 这个与前两个不同,因为事务没有重新启动。 相反,错误会传播并导致程序崩溃或被IO monad捕获。

如果这些是准确的(如果不是,请告诉我),我无法理解什么alwaysSucceeds可能做的。 always函数似乎是建立在它之上的,似乎可以在没有alwaysSucceeds情况下alwaysSucceeds

--This is probably wrong
always :: STM Bool -> STM ()
always stmBool = stmBool >>= check

alwaysSucceeds的文档说:

alwaysSucceeds添加了一个新的不变量,当传递给alwaysSucceeds时,在当前事务结束时以及每个后续事务结束时都必须为true。 如果它在任何这些点失败,那么违反它的事务将被中止,并且传播由不变量引发的异常。

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

alwaysSucceeds的特殊效果不是它在运行的地方检查失败的方式(单独运行“不变”操作应该做同样的事情),但它如何在事务结束时重新运行不变检查。

基本上,这个函数创建一个用户指定的不变量,如上面的(2)所示,它不仅要保持现在,还要保留在以后的事务结束时。

请注意,“事务”不是指STM monad中的每个子动作,而是指以atomically方式传递的组合动作。

我想a只是为了方便而删除,所以你不必将一个动作转换为STM () (例如使用void ),然后再将它传递给alwaysSucceeds 对于后来的重复检查,返回值无论如何都是无用的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM