Hi,

In the first example the traceShows are only called as a side effect of evaluating the IO expression (traceShow "Bla" $ do traceShow "Bloe" runit) which happens only once (runit is a top-level binding). I assume that for the second example GHC lifts (traceShow "Num" print 2) out of the do block and similarly evaluates it only once.

The traceShow "Bloe" is not lifted out of there because it's under a lambda. E.g. if you do this instead:

runit :: IO ()
runit = traceShow "Bla" $ do
  traceShow "Num" (print 2)
  traceShow "Bloe" runit

You get

"Bla"
"Num"
2
"Bloe"
2
2
2
2
...


Jacco

2017-06-28 16:16 GMT+01:00 Jurriaan Hage <J.Hage@uu.nl>:
We had a strange phenomenon while debugging a large compiler.
This is the smallest example, but we have seen this behavior in our own monad.

module TracEx where

import Debug.Trace

runit :: IO ()
runit = traceShow "Bla" $ do
  traceShow "Bloe” runit


and this generates
Bla
Bloe

and then it hangs. Nothing else is generated.
We are guessing this has to do with optimisations of some kind.

And what about

runit :: IO ()
runit = traceShow "Bla" $ do
  n <- traceShow "Num" print 2
  traceShow "Bloe” runit

Now we get
Bla
Num
2
Bloe
2
Bloe
2

No more Bla and no more Num.

Any ideas whether this is a bug or a feature?

Jur and Tibor



_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.