haskell的stm库中有一个函数具有以下类型的签名:
alwaysSucceeds :: STM a -> STM ()根据我在haskell中对STM的理解,在执行STM计算时,有三种方法可以“出错”(松散地使用该术语):
retry使其重新开始而触发的。这有效地使线程块,然后在读取集中的TVar更改后重试。throwSTM会导致这种情况。这个与前两个不同,因为事务不会重新启动。相反,错误会被传播,或者导致程序崩溃,或者在IO monad中被捕获。如果这些都是准确的(如果它们不是,请告诉我),我不明白alwaysSucceeds可能会做什么。always函数似乎是在其之上构建的,它似乎可以在没有alwaysSucceeds的情况下编写,如下所示:
--This is probably wrong
always :: STM Bool -> STM ()
always stmBool = stmBool >>= checkalwaysSucceeds的文档说:
alwaysSucceeds添加了一个新的不变量,在传递给alwaysSucceeds、当前事务结束和每个后续事务结束时必须为true。如果它在任何一个点上失败,那么违反它的事务就会被中止,由不变量引发的异常就会被传播。
但是由于参数的类型是STM a (多态在a中),所以它不能使用事务为决策的任何部分返回的值。所以,它似乎是在寻找我前面列出的不同类型的失败。但这有什么意义呢?STM monad已经处理了故障。在这个函数中包装它将如何影响它?为什么a类型的变量会被删除,从而导致STM ()
发布于 2014-09-07 05:17:43
alwaysSucceeds的特殊效果不是它在运行时如何检查失败(单独运行“不变”操作应该做同样的事情),而是它如何在事务结束时重新运行不变检查。
基本上,这个函数创建了一个用户指定的不变量,如上面(2)所示,它不仅要保持在现在,还必须在以后的事务结束时保持不变。
请注意,“事务”并不是指STM monad中的每个子操作,而是指传递给atomically的组合操作。
我想a是为了方便而放弃的,所以您不必在将操作传递给alwaysSucceeds之前将其转换为STM () (例如,使用void)。对于以后的重复检查,返回值无论如何都是无用的。
https://stackoverflow.com/questions/25705352
复制相似问题