如何在 Haskell 中强制评估? [英] How to force evaluation in Haskell?

查看:26
本文介绍了如何在 Haskell 中强制评估?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am relatively new to Haskell and I am trying to learn how different actions can be executed in sequence using the do notation. In particular, I am writing a program to benchmark an algorithm (a function)

foo :: [String] -> [String]

为此,我想写一个类似的函数

To this purpose I would like to write a function like

import System.CPUTime

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

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

The last line might need a conversion (e.g. to milliseconds) but this is not the topic of this question.

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

Is this the correct way to measure the time needed to compute function foo on some argument inputList?

换句话说,在动作end <- getCPUTime 执行之前,表达式foo inputList 会完全减少吗?还是 r 只会绑定到 thunk foo inputList?

In other words, will the expression foo inputList be completely reduced before the action end <- getCPUTime is executed? Or will r only be bound to the thunk foo inputList?

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

More in general, how can I ensure that an expression is completely evaluated before some action is executed?

这个问题是在几个月前针对程序员提出的(参见 此处) 并在那里有一个可接受的答案,但它已作为题外话关闭,因为它属于堆栈溢出.该问题无法移至堆栈溢出,因为它已超过 60 天.因此,在与版主一致的情况下,我在这里重新发布问题并自己发布已接受的问题,因为我认为它包含一些有用的信息.

This question was asked a few months ago on programmers (see here) and had an accepted answer there but it has been closed as off-topic because it belongs on stack overflow. The question could not be moved to stack overflow because it is older than 60 days. So, in agreement with the moderators, I am reposting the question here and posting the accepted question myself because I think it contains some useful information.

推荐答案

最初由用户 ysdx 给出的答案a> 关于程序员:

确实,您的版本不会对您的算法进行基准测试.由于 r 没有被使用,它根本不会被评估.

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

您应该可以使用 DeepSeq:

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

(a `deepseq` b) 是一些魔法"表达式,它强制在返回 b 之前对 a 进行完整/递归评估.

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

这篇关于如何在 Haskell 中强制评估?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆