开发者

How can I determine when an expression is evaluated?

I've 开发者_JAVA百科recently been learning haskell, and I understand the concept of lazy evaluation in general. One thing that I've discovered though is that it's often difficult to reason about exactly when an expression will be evaluated.

Is there a good way for getting information about precisely what is going on in terms of evaluation? Ideally I'd like to see something like a stack trace or a dependency list that shows when an expression needed to be evaluated, and what other expressions it depended on had to be evaluated.


Another possibility is to use Debug.Trace facility.


See here for an example of GHCi debugger session.


with the lazyness an expression is really evaluated if his value is needed in the rest of the code. In some situation you can have a program which not access to any elements of the data structure just because in your program you haven't use them :

import System.Environment    

-- this first version of the foo function evaluate a list (reversing) but don't use it any more
-- the result show that nothing is compute even the reverse du to the haskell lazyness
foo :: [a] -> IO ()
foo [] = print ("empty list")
foo xs = do let xs' = reverse xs in print ("reversable list")

-- this function evaluate the reversed list's length, so the compiler is oblige here to evaluate
-- both reverse and length
foo' :: [a] -> IO ()
foo' [] = print ("empty list")
foo' xs = do let xs' = reverse xs in print ("reversable list of size " ++ show (length xs'))    

main = do 
    [arg1, arg2] <- getArgs
    let listSize = read arg1
    let prog     = read arg2 
    if prog == 0 then foo (replicate listSize 'e') else foo' (replicate listSize 'e')  

Execution results show the following time execution

./stack1 100000000 0  -- calling the foo function with 100000000 elements
"reversable list"

real    0m0.003s
user    0m0.004s
sys  0m0.000s

time ./stack1 0 0 -- calling the foo function with an empty list
"empty list"

real    0m0.003s
user    0m0.004s
sys  0m0.004s

we observe that we have the same execution time. let try with foo'

time ./stack1 0 1 -- calling foo' with an empty list
"empty list"

real    0m0.003s
user    0m0.004s
sys  0m0.000s

time ./stack1 100000000 2
"reversable list of size 100000000"

real    0m8.662s -- here 8 minutes are spend to reverse and get the list length
user    0m7.944s
sys  0m0.716s
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜