`evaluate`、`rwhnf` 和 `seq` 与对应的 "deep" 之间有什么区别?
What are the differences between `evaluate`, `rwhnf` and `seq` and their "deep" counterparts?
在the wiki page about timing computations中有一个纯计算计时的例子。核心思想是使用函数 evaluate
、rnf
和 seq
来确保在两次调用 getCPUTime
:
time :: (Num t, NFData t) => t -> IO ()
time y = do
start <- getCPUTime
replicateM_ lim $ do
x <- evaluate $ 1 + y
rnf x `seq` return ()
end <- getCPUTime
我想在这里阐明函数evaluate
、rnf
和seq
的用法。
首先,evaluate
将其参数求值为弱头范式,但似乎它的另一个目的是处理求值过程中可能发生的异常。我不确定没有它会发生什么,但我准备假设异常处理需要它。
然后,rnf
将值计算为范式,以确保整个计算都在这里进行,并且由于调用 evaluate
.正如所讨论的那样,这可能是也可能不是人们想要的 here,因为可能不需要额外的评估。
最后,seq
确保表达式 rnf x
在返回 return ()
之前被评估为弱头部范式。
总结一下:evaluate
处理潜在的异常,rnf
深入评估 x
以确保整个计算是定时的,seq
确保 rnf x
及时评估。
这是我的问题:
- 对
seq
的调用与对 rnf
的调用是否多余,后者已经将值计算为正常形式?
- 如果我更愿意将评估时间设为弱头范式而不是范式,我可以简单地将
rnf
替换为 rwhnf
吗?那么这 3 个调用 evaluate
、rwhnf
和 seq
是否是多余的,这样我就可以消除对最后 2 个的使用并且只对 evaluate
感到满意?
对seq
的调用不是多余的,因为rnf x
需要求值(对WHNF)才能对x
求值为NF,也就是seq
的工作。
是的,我相信是这样:只是
evaluate $ 1 + y
return ()
但是!如果这里 evaluate
的目的是处理异常,我认为它不起作用,因为它们也可以从 rnf x
中抛出。如果不是,我看不到
的好处
rnf (1 + y) `seq` return ()
force
和 evaluate
文档都提出了一个更简单的替代方案:
evaluate $ force $ 1 + y
return ()
也许该页面是在 force
可用之前写的?尽管如此,除非我遗漏了什么,
evaluate $ rnf $ 1 + y
会正确完成工作。
在the wiki page about timing computations中有一个纯计算计时的例子。核心思想是使用函数 evaluate
、rnf
和 seq
来确保在两次调用 getCPUTime
:
time :: (Num t, NFData t) => t -> IO ()
time y = do
start <- getCPUTime
replicateM_ lim $ do
x <- evaluate $ 1 + y
rnf x `seq` return ()
end <- getCPUTime
我想在这里阐明函数evaluate
、rnf
和seq
的用法。
首先,evaluate
将其参数求值为弱头范式,但似乎它的另一个目的是处理求值过程中可能发生的异常。我不确定没有它会发生什么,但我准备假设异常处理需要它。
然后,rnf
将值计算为范式,以确保整个计算都在这里进行,并且由于调用 evaluate
.正如所讨论的那样,这可能是也可能不是人们想要的 here,因为可能不需要额外的评估。
最后,seq
确保表达式 rnf x
在返回 return ()
之前被评估为弱头部范式。
总结一下:evaluate
处理潜在的异常,rnf
深入评估 x
以确保整个计算是定时的,seq
确保 rnf x
及时评估。
这是我的问题:
- 对
seq
的调用与对rnf
的调用是否多余,后者已经将值计算为正常形式? - 如果我更愿意将评估时间设为弱头范式而不是范式,我可以简单地将
rnf
替换为rwhnf
吗?那么这 3 个调用evaluate
、rwhnf
和seq
是否是多余的,这样我就可以消除对最后 2 个的使用并且只对evaluate
感到满意?
对
seq
的调用不是多余的,因为rnf x
需要求值(对WHNF)才能对x
求值为NF,也就是seq
的工作。是的,我相信是这样:只是
evaluate $ 1 + y return ()
但是!如果这里 evaluate
的目的是处理异常,我认为它不起作用,因为它们也可以从 rnf x
中抛出。如果不是,我看不到
rnf (1 + y) `seq` return ()
force
和 evaluate
文档都提出了一个更简单的替代方案:
evaluate $ force $ 1 + y
return ()
也许该页面是在 force
可用之前写的?尽管如此,除非我遗漏了什么,
evaluate $ rnf $ 1 + y
会正确完成工作。