Data.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
会存在?
发布于 2015-06-01 18:56:48
如果您的第一个版本中的{- Do stuff -}
直接将keepRunning
分配给某些计算的结果,那么您当然可以轻松地重写它,使该计算成为递归的条件,并消除IORef
。这将是较好的解决办法。
但是,如果您的第一个版本在其他函数中设置了keepRunning
,那么等效的ref-less版本可能会变得非常复杂。因此,在这种情况下,哪个版本更可取就不那么清楚了。不过,你可以指出,这样的设计从一开始就会很糟糕。如果不知道{- Do stuff -}
实际做了什么,就很难说出任何具体的内容。
包含递归的do块会比do块外部的程序慢吗?
不是的。
如果您可以用函数替换Data.IORef的每个实例,那么为什么Data.IORef会存在?
根据您使用的API,您可能无法使用(例如,在非玻璃钢GUI库中有事件处理程序)。此外,在某些情况下,您可以删除IORef,但只能通过损害性能和/或使代码更加复杂。
尽管如此,使用IORef
作为循环条件的示例几乎可以肯定地说,您可以在没有IORef
的情况下编写更好的版本。
https://stackoverflow.com/questions/30580185
复制相似问题