首页 > 解决方案 > 出于效率目的使用 ST monad

问题描述

我有一些需要优化的传统状态传递代码。我听说如果你经常维护和更新状态,那么使用STmonad 可以帮助提高效率。但是,在稍微研究了一下这些ST东西之后,我有点不清楚应该如何/在哪里使用STmonad。

想到的几种方法:

  1. 而不是到处传递状态,而是传递STRef's 。例如,foo :: State -> a -> b -> (State,c)变得foo :: STRef s State -> a -> b -> ST s c等等。

  2. 保持我的函数签名相同,但ST在后台使用runST.

  3. ST在我的主执行循环中更新状态并ST使用runST或转义时使用stToIO

显然,这些问题最终将取决于我的项目的具体情况,但我想知道在需要更多细节之前是否有任何可能有用的经验法则类型指南。

标签: haskell

解决方案


在一般情况下,只有方法 1 似乎是可行的。

runST action返回并传递其结果时,它将释放所有已分配的运行actionusing的内存newSTRef。如果runST每个函数使用一个,则不能在函数调用之间保留任何引用。即使您不需要,让每个函数调用在入口时分配其可变状态,仅在退出时释放它(如您的选项 2 所示)看起来毫无意义。我会绕过一个STRef s State,并通过它改变状态。

不过,可能还有其他方面需要考虑。如果一个函数在内部执行了许多突变,那么选项 2 可能仍然可以,因为进入/离开的额外成本可以忽略不计。

(我可能不完全理解您的选项3。本质上不是选项1吗?)


推荐阅读