首页
学习
活动
专区
圈层
工具
发布

Haskell
EN

Stack Overflow用户
提问于 2014-09-06 22:28:42
回答 1查看 522关注 0票数 11

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

代码语言:javascript
复制
alwaysSucceeds :: STM a -> STM ()

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

  1. 已读取的TVar的值由另一个线程更改。
  2. 违反用户指定的不变量。这似乎通常是通过调用retry使其重新开始而触发的。这有效地使线程块,然后在读取集中的TVar更改后重试。
  3. 引发异常。调用throwSTM会导致这种情况。这个与前两个不同,因为事务不会重新启动。相反,错误会被传播,或者导致程序崩溃,或者在IO monad中被捕获。

如果这些都是准确的(如果它们不是,请告诉我),我不明白alwaysSucceeds可能会做什么。always函数似乎是在其之上构建的,它似乎可以在没有alwaysSucceeds的情况下编写,如下所示:

代码语言:javascript
复制
--This is probably wrong
always :: STM Bool -> STM ()
always stmBool = stmBool >>= check

alwaysSucceeds的文档说:

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

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-09-07 05:17:43

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

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

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

我想a是为了方便而放弃的,所以您不必在将操作传递给alwaysSucceeds之前将其转换为STM () (例如,使用void)。对于以后的重复检查,返回值无论如何都是无用的。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25705352

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档