Hi cafe,

Look how one can watch the evaluation tree of a computation, to debug laziness-related problems.

{-# LANGUAGE BangPatterns #-}
module HTrace where

import Data.List (foldl')
import Data.IORef
import System.IO.Unsafe

level = unsafePerformIO $ newIORef 0

htrace str x = unsafePerformIO $ do
  lvl <- readIORef level
  putStrLn (replicate (4*lvl) ' ' ++ str)
  writeIORef level (lvl+1)
  let !vx = x
  writeIORef level lvl
  return vx

xs = map (\x -> htrace (show x) x) [1..10]

s = foldl (\a b -> htrace "+" (a+b)) 0 xs
s2 = foldl' (\a b -> htrace "+" (a+b)) 0 xs

b = htrace "b" 2
c = htrace "c" 3
a = htrace "a" $ b + c
x = htrace "x" $ b + c

*HTrace> a
a
    b
    c
5
*HTrace> x
x
5

*HTrace> s
+
    +
        +
            +
                +
                    +
                        +
                            +
                                +
                                    +
                                        1
                                    2
                                3
                            4
                        5
                    6
                7
            8
        9
    10
55

(reload)
*HTrace> s2
+
    1
+
    2
+
    3
+
    4
+
    5
+
    6
+
    7
+
    8
+
    9
+
    10
55

--
Eugene Kirpichov
Principal Engineer, Mirantis Inc. http://www.mirantis.com/
Editor, http://fprog.ru/