haskell - 如何在 Haskell 中强制评估?

标签 haskell lazy-evaluation

我对 Haskell 比较陌生,我正在尝试学习如何使用 do 表示法按顺序执行不同的操作。
特别是,我正在编写一个程序来对算法(一个函数)进行基准测试

foo :: [String] -> [String]

为此,我想编写一个类似的函数
import System.CPUTime

benchmark :: [String] -> IO Integer
benchmark inputList = do
                         start <- getCPUTime
                         let r = foo inputList
                         end <- getCPUTime
                         return (end - start) -- Possible conversion needed.

最后一行可能需要转换(例如到毫秒),但这不是这个问题的主题。

这是测量在某些参数 inputList 上计算函数 foo 所需时间的正确方法吗?

换句话说,表达式 foo inputList在行动前完全减少end <- getCPUTime被执行?或将r只绑定(bind)到 thunk foo inputList ?

更一般地说,如何确保在执行某些操作之前完全评估表达式?

几个月前,程序员曾问过这个问题(见 here),并在那里得到了一个公认的答案,但由于它属于堆栈溢出,因此它已被关闭为题外话。该问题无法移至堆栈溢出,因为它已超过 60 天。因此,与版主一致,我在这里重新发布问题并自己发布已接受的问题,因为我认为它包含一些有用的信息。

最佳答案

最初由用户 ysdx 给出的答案on programmers :

Indeed you version will not benchmark your algorithm. As r is not used it will not be evaluated at all.

You should be able to do it with DeepSeq:

benchmark :: [String] -> IO Integer
benchmark inputList = do
                     start <- getCPUTime
                     let r = foo inputList
                     end <- r `deepseq` getCPUTime
                     return (end - start)

(a `deepseq` b) is some "magic" expression which forces the complete/recursive evaluation of a before returning b.

关于haskell - 如何在 Haskell 中强制评估?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14163072/

相关文章:

exception - 如何处理这个异常呢?

haskell - 是否可以通过修改这个简单的 reducer 来展示不同的评估策略?

Haskell——Rand monad 中的计算超时

haskell - Haskell Servant从处理程序获取当前路由/URL

Haskell:让列表理解产生意想不到的结果

haskell - 测试列表是否已排序

haskell - 在另一个字符串 Haskell 中查找子字符串的索引

python - 在 Python 中延迟评估/惰性评估

scala - 如何强制执行惰性值计算

java - 可选的map()和filter()操作类型