STRef 和 IORef 之间到底有什么区别,我什么时候使用它们?据我所知,它们都是可变状态,那么它们存在的意义何在?
问问题
3092 次
2 回答
29
你可以在 monad 中做IO
比在ST
monad 中更多的事情。后者提供可变引用,前者提供可变引用、异常捕获、线程,当然还有 IO。
使用可以解决您的问题的“最弱”或“更受限制”的工具通常是一个很好的 Haskell 实践,因为“更弱”的工具往往更容易理解和分析(这个原则在 Haskell 中出现的另一个地方是Applicative
与Monad
区别)。
因此,如果您只需要可变引用,请使用ST
. 未来的维护者将能够通过查看类型来推断更多关于你的函数做什么(和不做什么)的事情。
您被迫使用IORef
s(或它们的表亲MVar
s)的一个示例情况是,必须在两个不同的执行线程之间共享一个可变引用。
还要记住,你可以逃逸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 回答