什么时候使用STRef或IORef?

时间:2013-12-07 08:23:49

标签: haskell ioref

STRef与IORef的区别究竟是什么?我何时使用它们?据我所知,他们两个都是可变的状态,所以两者都存在吗?

2 个答案:

答案 0 :(得分:25)

您可以在IO monad中执行比ST monad更多的操作。后者提供了可变引用,前者提供了可变引用,异常捕获,线程,当然还有IO。

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

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

您必须在两个不同的执行线程之间共享可变引用时,您被迫使用IORef s(或它们的堂兄MVar)的示例情况。

另请注意,您可以转义ST(这意味着您可以在纯函数中运行ST次计算),但无法转义IO

答案 1 :(得分:9)

它们各自提供相同的功能,但适用于不同的monad。如果您需要IORef中的托管参考,请使用IO;如果STRef中需要托管参考,请使用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