Send Beginners mailing list submissions to
[email protected]
To subscribe or unsubscribe via the World Wide Web, visit
http://www.haskell.org/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
[email protected]
You can reach the person managing the list at
[email protected]
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."
Today's Topics:
1. Using Debug.Trace (Patrick LeBoutillier)
2. Re: Using Debug.Trace (Daniel Fischer)
3. Re: Using Debug.Trace (Edward Z. Yang)
4. Re: Using the state monad. (dan portin)
5. Optimization Problem ([email protected])
----------------------------------------------------------------------
Message: 1
Date: Sun, 8 Aug 2010 13:14:41 -0400
From: Patrick LeBoutillier <[email protected]>
Subject: [Haskell-beginners] Using Debug.Trace
To: beginners <[email protected]>
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=ISO-8859-1
Hi all,
I'm writing a parser for a binary format, and I'm trying to debug it
since I have a bug and the code is getting lost in the bits and bytes.
Basically my main is like this:
import Data.Binary.Get
import Debug.Trace
import qualified Data.ByteString.Lazy as L
main = do
bytes <- L.readFile "song.gp4"
let (version, bytes') = getVersion bytes
putStrLn version
let stuff = runGet (getDocument version) bytes'
putStrLn $ show stuff
return ()
The getVersion and getDocument functions use the Data.Binary.Get monad
to decode the byte string into various objects.
I tried sprinkling "trace" calls a bit everywhere and I realize they
don't always get called at the expected time. Most of them are only
called when I reach the "putStrLn $ show stuff" statement.
Unfortunately that doesn't help me because I get a
*** Exception: too few bytes. Failed reading at byte position 35939
before that.
Is this happening because I'm using lazy IO to read the file?
Is there a way to force the evaluation of these "trace" calls?
Are there any other ways to debug this kind of stuff in Haskell?
Thanks a lot,
Patrick
--
=====================
Patrick LeBoutillier
Rosemère, Québec, Canada
------------------------------
Message: 2
Date: Sun, 8 Aug 2010 20:18:55 +0200
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Using Debug.Trace
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="iso-8859-1"
On Sunday 08 August 2010 19:14:41, Patrick LeBoutillier wrote:
> Hi all,
>
> I'm writing a parser for a binary format, and I'm trying to debug it
> since I have a bug and the code is getting lost in the bits and bytes.
> Basically my main is like this:
>
> import Data.Binary.Get
> import Debug.Trace
> import qualified Data.ByteString.Lazy as L
>
> main = do
> bytes <- L.readFile "song.gp4"
> let (version, bytes') = getVersion bytes
> putStrLn version
>
> let stuff = runGet (getDocument version) bytes'
> putStrLn $ show stuff
putStrLn $ show stuff === print stuff
>
> return ()
Unneeded
>
> The getVersion and getDocument functions use the Data.Binary.Get monad
> to decode the byte string into various objects.
> I tried sprinkling "trace" calls a bit everywhere and I realize they
> don't always get called at the expected time.
trace prints its first argument when the second is demanded, so to print
earlier, you can in general add more strictness to your programme, but I'm
not sure if that makes a difference for Get, since that has no freedom to
reorder the sequence in which the values are read. So with traces in the
right places, you should get tracing output while the deserialisation is
underway automatically.
Whether in
getSomeObject = do
foo <- get
!bar <- trace ("foo is " ++ show foo) get
let !baz = trace ("bar is " ++ show bar) $ fiddle foo bar
return $! trace ("baz is " ++ show baz) (wibble baz foo bar)
the bangs make a difference regarding trace output, I don't know.
> Most of them are only
> called when I reach the "putStrLn $ show stuff" statement.
> Unfortunately that doesn't help me because I get a
>
> *** Exception: too few bytes. Failed reading at byte position 35939
>
> before that.
That usually means the file hasn't the correct format, e.g. some size
(length of list) has been written in little-endian order and is read in
big-endian, so get tries to read more items than there are.
>
> Is this happening because I'm using lazy IO to read the file?
Unlikely. What is the file size on disk? If it's larger than 35939 bytes,
you have an IO problem, but still Data.ByteString.Lazy.readFile wouldn't be
the first on my list of suspects.
> Is there a way to force the evaluation of these "trace" calls?
Seeing more of the code could help coming up with ideas.
> Are there any other ways to debug this kind of stuff in Haskell?
>
Break things down into smaller pieces and test those.
And there's the ghci-debugger, I hear if one has learned to use it, it's
quite helpful.
>
> Thanks a lot,
>
> Patrick
------------------------------
Message: 3
Date: Sun, 08 Aug 2010 14:20:38 -0400
From: "Edward Z. Yang" <[email protected]>
Subject: Re: [Haskell-beginners] Using Debug.Trace
To: Patrick LeBoutillier <[email protected]>
Cc: beginners <[email protected]>
Message-ID: <1281291344-sup-...@ezyang>
Content-Type: text/plain; charset=UTF-8
Excerpts from Patrick LeBoutillier's message of Sun Aug 08 13:14:41 -0400 2010:
> The getVersion and getDocument functions use the Data.Binary.Get monad
> to decode the byte string into various objects.
> I tried sprinkling "trace" calls a bit everywhere and I realize they
> don't always get called at the expected time. Most of them are only
> called when I reach the "putStrLn $ show stuff" statement. [snip]
>
> Is this happening because I'm using lazy IO to read the file?
> Is there a way to force the evaluation of these "trace" calls?
> Are there any other ways to debug this kind of stuff in Haskell?
To be more precise, this is happening because Haskell is processing
the file lazily. My feeling is forcing the evaluation of the trace
calls using seq or similar won't be too helpful, because your error
is earlier than that, in your definition of the Get monad. If you
trace in the monad before you exhaust the input stream, you should
get useful info; the function getRemainingLazyByteString may also
come in handy.
Cheers,
Edward
------------------------------
Message: 4
Date: Sun, 8 Aug 2010 12:48:10 -0700
From: dan portin <[email protected]>
Subject: Re: [Haskell-beginners] Using the state monad.
To: Stephen Tetley <[email protected]>, [email protected]
Message-ID:
<[email protected]>
Content-Type: text/plain; charset="iso-8859-1"
Hi Stephen, thanks for your reply:
In the code above Tableau is the same type after rewriting. If that's
> the case, maybe you don't need a state monad solution. However, if you
> are labelling something with /w/ which looks like an integer from your
> explanation, then first you want to make a variation of the Tableau
> datatype that holds the label, thus rewrite would be a type changing
> function:
>
> rewrite :: Tableau -> Tableau'
>
I think the basic tableau data type would look like:
data Tableau = Node (World, Expr) [Tableau]
type World = Int
and the rewrite function would need to track the current position of rewrite
in the tableau and store a complete tableau (or some kind of record,
possibly
in a zipper) in order to move around, depending on the instruction it's
given. So
I would need something like:
rewrite :: Tableau -> State (Record, Tableau)
So that it could be passed an instruction such as:
(Poss, [ex]) -> (a) inject ex into Tableau; (b) Store
Tableau in Record; (c) move to correct spot in Record;
(d) restart rewriting from position in Record.
Even though Haskell's my first language, I still want a function that says:
store
current Tableau in *r, then get r* and restart.
> If this is what you want to do, you should be able to thread "number
> supply" through the rewrite and rule functions fairly simply with a
> state monad.
>
> rewrite :: Tableau -> State Int Tableau'
>
I think this means that when implementing the monad, I should define (>>=)
as a
general rule similar to the set of instructions above, e.g,. if f is a
function that
injects the list ex into a tree structure, and g is a rewrite function, then
>>= should
have a structure abstracted from the following:
f >>= g = do f ~> State Record Tableau
store Tableau in Record
do g at Record
make Record into current Tableau
This seems similar to the "threading" method that, for instance, Wadler uses
in the first
sections of his paper on functional programming and monads, when building an
evaluator
that keeps track of division operations.
Thanks or the response. If you see any glaring 'monadic errors,' I'd be
happy to hear about
them, but your advice was helpful :)
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
http://www.haskell.org/pipermail/beginners/attachments/20100808/f1e439d2/attachment-0001.html
------------------------------
Message: 5
Date: Mon, 9 Aug 2010 13:16:54 +0530 (IST)
From: [email protected]
Subject: [Haskell-beginners] Optimization Problem
To: [email protected]
Message-ID:
<1213367536.77238.1281340014458.javamail.javamailu...@localhost>
Content-Type: text/plain; charset="utf-8"
Skipped content of type multipart/alternative-------------- next part
--------------
A non-text attachment was scrubbed...
Name: exper.hs
Type: text/x-haskell
Size: 2864 bytes
Desc: not available
Url :
http://www.haskell.org/pipermail/beginners/attachments/20100809/354d977b/exper.bin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: exper.prof
Type: application/octet-stream
Size: 4765 bytes
Desc: not available
Url :
http://www.haskell.org/pipermail/beginners/attachments/20100809/354d977b/exper.obj
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 26, Issue 18
*****************************************