with laziness, an expression is really evaluated if its value is needed in the rest of the code. In some situation, you may have a program that does not have access to any elements of the data structure just because you do not use them in your program:
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 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')
Run Results Shows Next Run Time
./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
note that we have the same runtime. 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
source
share