[Haskell-beginners] Issue with lazy eval + trace

Daniel Fischer daniel.is.fischer at googlemail.com
Mon Nov 7 14:47:14 CET 2011

On Monday 07 November 2011, 09:41:24, Hugo Ferreira wrote:
> Hello,
> I am using "import Debug.Trace" to debug some code but it is
> not working as expected. I believe this is due to lazy evaluation.
> But I cannot see how I can circumvent it. To exemplify I have
> the following function:
> tagFun :: (POSTags -> Tag) -> POSTags -> POSTags
> tagFun f corpus = Z.foldlz' tag Z.empty corpus
>    where
>        tag acc z = Z.insert newTag acc
>         where
>           (token, correctTag, _proposdTag) = trace "cursor " Z.cursor z
>           proposed = trace "proposed tag" (f z)
>           newTag = ( token, correctTag, proposed )
> If I place tracing at:
>        tag acc z = trace ("tag "++token++" = "++ show newTag) Z.insert
> newTag acc
> then it works ok. However the lines
>           (token, correctTag, _proposdTag) = trace "cursor " Z.cursor z
>           proposed = trace "proposed tag" (f z)
> don't work. They only appear once. I assume they should appear with
> every element in the zipper. Can anyone explain why?

You're compiling with optimisations, aren't you?
You need the trace strings to depend on the input, otherwise the optimiser 
sees no reason to repeat the work. (The constant part is lifted out of the 
lambda, a consequence of unsafePerformIO.)

The line `trace "cursor " Z.cursor z' actually shouldn't print multiple 
traces even without optimisations, since it's

(trace "cursor " Z.cursor) z

so the trace applies to the evaluation of the function Z.cursor, which 
should only be done once.

More information about the Beginners mailing list