[Haskell-cafe] Hierarchical tracing for debugging laziness

HASHIMOTO, Yusaku nonowarn at gmail.com
Wed Jan 25 00:39:02 CET 2012


Great, It illustrates why difference lists are awesome.

import HTrace

app :: [a] -> [a] -> [a]
app [] ys = htrace "app" ys
app (x:xs) ys = htrace "app" (x:app xs ys)

rev1 [] = htrace "[]" []
rev1 (x:xs) = htrace "rev1" (app (rev1 xs) [x])

rev2 []     ys = htrace "ys" ys
rev2 (x:xs) ys = htrace ":" (rev2 xs (x:ys))

*Main> rev1 [1..10]
rev1
    rev1
        rev1
            rev1
                rev1
                    rev1
                        rev1
                            rev1
                                rev1
                                    rev1
                                        []
                                        app
                                    app
                                app
                            app
                        app
                    app
                app
            app
        app
    app
[10app
app
app
app
app
app
app
app
app
,9app
app
app
app
app
app
app
app
,8app
app
app
app
app
app
app
,7app
app
app
app
app
app
,6app
app
app
app
app
,5app
app
app
app
,4app
app
app
,3app
app
,2app
,1]
*Main> rev2 [1..10]

<interactive>:4:1:
    No instance for (Show ([a0] -> [a0]))
      arising from a use of `print'
    Possible fix: add an instance declaration for (Show ([a0] -> [a0]))
    In a stmt of an interactive GHCi command: print it
*Main> rev2 [1..10] []
:
    :
        :
            :
                :
                    :
                        :
                            :
                                :
                                    :
                                        ys
[10,9,8,7,6,5,4,3,2,1]

Thanks for sharing!

On 25 January 2012 01:47, Eugene Kirpichov <ekirpichov at gmail.com> wrote:
> 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/
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>



More information about the Haskell-Cafe mailing list