【发布时间】:2015-08-15 07:22:31
【问题描述】:
数据.IORef
keepRunning <- newIORef True
let loop = do
running <- readIORef keepRunning
if running then
do
{- Do stuff -}
loop running
return ()
else
do
{- Do stuff -}
return ()
递归
let keepRunning = True
let loop running = if running then
do
{- Do stuff -}
loop running
return ()
else do
{- Do stuff -}
return ()
loop keepRunning
有什么理由更喜欢上述方法之一吗?与 do 块外相比,包含递归的 do 块会减慢程序速度吗?如果可以用函数替换Data.IORef 的每个实例,那为什么Data.IORef 还存在呢?
【问题讨论】:
-
您不能“用函数替换 Data.IORef 的每个实例”——您为什么相信这一点?在一些简单的情况下你可以,但通常你不能。也许您可以执行整个程序转换以消除所有
IORefs,但这种转换不是本地的,并且需要大量的状态传递。 -
IORef对并发很有用。我最近还将它与一些 FFI 代码一起使用,其 API 要求我传递一些回调:: Foo -> IO ()以被多次调用(因此IORef用于跟踪状态)。当递归就足够时不使用它的原因与隐式状态使程序更加混乱、容易出错、难以重构等原因都是相同的。
标签: variables haskell recursion io reference