When to use STRef or IORef?

不打扰是莪最后的温柔 提交于 2019-12-04 00:02:32

You can do more things in the IO monad than in the ST monad. The latter provides mutable references, the former provides mutable references, exception catching, threads, and of course IO.

It is usually good Haskell practice to use the "weakest" or "more restricted" tool available that can solve your problem, because "weaker" tools tend to be easier to understand and analyze (another place this principle crops up in Haskell is in the Applicative versus Monad distinction).

So, if you only need mutable references, use ST. Future maintainers will be able to infer more about what your function does (and doesn't do) just by looking at the type.

An example situation in which you are forced to use IORefs (or their cousins MVars) is when having to share a mutable reference between two different execution threads.

Also keep in mind that you can escape ST (which means you can run ST computations inside pure functions) but you can't escape IO.

They each provide the same functionality, but for different monads. Use IORef if you need a managed ref in IO, and STRef if you need one in ST s.

EDIT: a brief example:

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
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!