[Haskell-beginners] Caching evaluation of lazy lists

Daniel Fischer daniel.is.fischer at web.de
Fri Oct 23 13:34:44 EDT 2009


Am Freitag 23 Oktober 2009 18:30:53 schrieb Philip Scott:
> Hello again,
>
> > then, barring memory pressure forcing it out, it will be computed only
> > once (each list element will be computed only once, when it's first
> > needed).
>
> Thanks Daniel, that was what I was after. Is there any way of
> investigating these things without using the profiler? E.g. is there any
> way to stick a debug print statement inside a function without moving
> over to sideeffects and IO Monads etc.. I know printing is a side
> effect, but it would be nice to say 'I can has itsy sneeky side effect
> plz Haskell, just for little testing while'
>
> Cheers,
>
> Philip

import Debug.Trace

infixl 0 `debug`

debug = flip trace

dfib :: Int -> Integer
dfib =
    let fib 0 = 0
        fib 1 = 1
        fib n = dfib (n-2) + dfib (n-1) `debug` "eval fib " ++ show n
    in (map fib [0 .. ] !!)

Ok, modules loaded: MFib.
*MFib> dfib 4
eval fib 4
eval fib 2
eval fib 3
3
*MFib> dfib 7
eval fib 7
eval fib 5
eval fib 6
13
*MFib> dfib 15
eval fib 15
eval fib 13
eval fib 11
eval fib 9
eval fib 8
eval fib 10
eval fib 12
eval fib 14
610
*MFib>

The trick with debug = flip trace makes commenting out the debug-code easier:

fun x = trace ("fun " ++ show x) $ body x

~>

fun x = {- trace ("fun " ++ show x) $ -} body x

vs.

fun x = body x `debug` "fun " ++ show x

~>

fun x = body x -- `debug` "fun " ++ show x

But beware, including the argument in the trace message can lead to recalculation of 
values which would be cached without it, it's a hairy issue.


More information about the Beginners mailing list