[Haskell] A few newbie questions about tracing/debugging and order of execution

Cale Gibbard cgibbard at gmail.com
Wed Dec 28 12:49:29 EST 2005


Hi,

Mostly I just use ghci. If something isn't working (or even sometimes
if it is), I break it down into smaller parts until I can understand
and test each part separately. Usually once the functions are broken
into small, easy to manage pieces, it becomes obvious where the error
is.

Sometimes though, in certain kinds of algorithms, you have some code
which runs for quite a long time before producing an example of data
on which it fails. For this purpose, Debug.Trace is quite handy for
extracting a report of the input data where things are breaking, but I
usually find that these cases are pretty rare, and Debug.Trace is
still no substitute for decomposing your problem further.

 - Cale

On 28/12/05, Hunter Kelly <retnuh at gmail.com> wrote:
> Yes, thank you, that did the trick!  It produced the output for all steps,
> and in the order I would expect.
>
> Are there other techniques that people use to get debugging output?
>
> H
>
> On 12/28/05, Robert Dockins <robdockins at fastmail.fm> wrote:
> >
> > On Dec 28, 2005, at 6:10 AM, Hunter Kelly wrote:
> >
> > > Heya, I decided to play around with Haskell and see what it's like.
> > > I used a small problem to explore it.  Basically, given two words,
> > > find the least number of 1 letter changes that will go from one
> > > word to the other (e.g.  for "fig" and "dog" either fig -> fog ->
> > > dog  or
> > > fig -> dig -> dog).
> > >
> > > I came up with a solution, but I have to say it was quite difficult to
> > > get any debugging information, and when I did, the result was fairly
> > > surprising!
> >
> >
> > I see you are using Debug.Trace to generate your debug messages.  The
> > 'trace' function is a sort of strange one, because it breaks the
> > usual rules that Haskell follows; it allows you to generate output in
> > the middle of a pure computation.  It works by generating output
> > _when it is evaluated_.  However, without the IO monad to make
> > everything sequenced and well-behaved, it can be difficult to predict
> > when that will occur.  In the particular program you posted, the
> > 'trace' thunk is not evaluated until after the recursive call has
> > completed, which gives the reversed output.  Furthermore, when there
> > is no solution, the 'trace' thunk isn't evaluated at all (the magic
> > of laziness!), so you never see that output.
> >
> > To make your traces show up where you expect, you need to make sure
> > that your trace function gets forced earlier and on both success and
> > failure paths.  Since your function is written as a big let...in
> > if ...  block you can do something like this:
> >
> >    ..... =
> >      let ...
> >           ....
> >      in trace traceString
> >           (if ...
> >               then
> >               else
> >            )
> >
> > That way, the trace will be output before the 'if' is evaluated, so
> > you will get output for both branches.  I can't tell from a quick
> > inspection if it will return the results in the order you expect, but
> > I think it may.
> >
> >
> >
> > Rob Dockins
> >
> > Speak softly and drive a Sherman tank.
> > Laugh hard; it's a long way to the bank.
> >            -- TMBG
> >
> >
> _______________________________________________
> Haskell mailing list
> Haskell at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell
>


More information about the Haskell mailing list