Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force evaluation in Haskell?

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.

like image 874
Giorgio Avatar asked Jan 04 '13 18:01

Giorgio


People also ask

Why Haskell is lazy evaluation?

Haskell is a lazy language. It does not evaluate expressions until it absolutely must. This frequently allows our programs to save time by avoiding unnecessary computation, but they are at more of a risk to leak memory. There are ways of introducing strictness into our programs when we don't want lazy evaluation.

Is Haskell lazy evaluation?

Haskell is a lazy language, meaning that it employs lazy evaluation . Before explaining lazy evaluation , let's first explain strict evaluation which most readers will likely be more familiar with. Strict evaluation means that arguments to functions are evaluated prior to being passed to the functions.

What is strictness in Haskell?

Strictness analysis Optimising compilers like GHC try to reduce the cost of laziness using strictness analysis, which attempts to determine which function arguments are always evaluated by the function, and hence can be evaluated by the caller instead.

How does lazy evaluation work?

In programming language theory, lazy evaluation, or call-by-need, is an evaluation strategy which delays the evaluation of an expression until its value is needed (non-strict evaluation) and which also avoids repeated evaluations (sharing).


1 Answers

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.

like image 108
6 revs, 3 users 64% Avatar answered Sep 21 '22 17:09

6 revs, 3 users 64%