23

STRef 和 IORef 之间到底有什么区别,我什么时候使用它们?据我所知,它们都是可变状态,那么它们存在的意义何在?

4

2 回答 2

29

你可以在 monad 中做IO比在STmonad 中更多的事情。后者提供可变引用,前者提供可变引用、异常捕获、线程,当然还有 IO。

使用可以解决您的问题的“最弱”或“更受限制”的工具通常是一个很好的 Haskell 实践,因为“更弱”的工具往往更容易理解和分析(这个原则在 Haskell 中出现的另一个地方是ApplicativeMonad区别)。

因此,如果您需要可变引用,请使用ST. 未来的维护者将能够通过查看类型来推断更多关于你的函数做什么(和不做什么)的事情。

您被迫使用IORefs(或它们的表亲MVars)的一个示例情况是,必须在两个不同的执行线程之间共享一个可变引用。

还要记住,你可以逃逸ST(这意味着你可以ST在纯函数中运行计算)但你不能逃逸IO

于 2013-12-07T08:59:03.607 回答
10

它们每个都提供相同的功能,但用于不同的 monad。如果IORef您需要一个托管 ref in IO,并且STRef如果您需要一个 in ,请使用ST s

编辑:一个简单的例子:

import Control.Monad.ST
import Data.IORef
import Data.STRef

exampleSTRef :: ST s Int
exampleSTRef = do
  counter <- newSTRef 0
  modifySTRef counter (+ 1)
  readSTRef counter

exampleIORef :: IO Int
exampleIORef = do
  counter <- newIORef 0
  modifyIORef counter (+ 1)
  putStrLn "im in ur IO monad so i can do I/O"
  readIORef counter
于 2013-12-07T08:28:54.060 回答