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

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

问题描述

我对Haskell相对较新,我正试图学习如何使用符号按顺序执行不同的动作。
特别是,我正在编写一个程序来对一个算法进行基准测试(一个函数)

pre $ f $ foo :: [String] - > [String]

为了达到这个目的,我想编写一个像

  import System.CPUTime 

benchmark :: [String] - > IO Integer
benchmark inputList = do
start< - getCPUTime
let r = foo inputList
end< - getCPUTime
return(end - start) - 可能需要转换。

最后一行可能需要转换(例如以毫秒为单位),但这不是此问题的主题。

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



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



一般来说,我怎样才能确保表达式在执行某个动作前被完全评估?
$ b


几个月前,程序员问过问题(请参阅此处)和在那里有一个被接受的答案,但由于它属于堆栈溢出,所以它已被关闭作为脱离主题。这个问题不能转移到堆栈溢出,因为它超过了60天。因此,与版主协商一致,我在此转贴问题并自行发布接受的问题,因为我认为它包含一些有用的信息。

答案最初由用户 ysdx on programmers


确实,您的版本不会基准测试你的算法。因为 r 没有被使用,所以根本不会被评估。

你应该可以用< a href =http://www.haskell.org/ghc/docs/7.4.1/html/libraries/deepseq-1.3.0.0/Control-DeepSeq.html =nofollow noreferrer> 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 的完整/递归评估。



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.

Is this the correct way to measure the time needed to compute function foo on some argument 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?


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.

解决方案

Answer originally given by user 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中强制进行评估?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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