[Haskell-beginners] Extract and integer from a ByteString

Tom Hobbs tvhobbs at gmail.com
Mon Jun 14 17:05:34 EDT 2010


Hi all,

Can anyone help me with this problem I'm been banging my head against for  
a while?

I have a stream of bytes that I want to read, the stream is formatted thus;

null, null, null, 4, 'd', 'a', 't', 'a'<end of stream>

Where the first four bytes tell me the number of bytes I should read next  
in order to get some string value.

What I have is code similar to the following;

readFromStream address port	=
                 do
                 h <- connectTo address (PortNumber port)
                 hSetBuffering h NoBuffering
                 L.hPut h (encode (0xFAB10000 :: Word32))
                 p <- L.hGet h 4
                 readData h (extractInt((L.unpack p)))

extractInt      = foldl addDigit 0
                 where
                 addDigit num d = 10*num + d

readData h c    = do
                 print c
                 s <- L.hGet h c
                 print s

(Note: extractInt is largely copied from a Stack Overflow answer to  
something else.)

The problem with this code in GHCI is;

     Couldn't match expected type `Int' against inferred type `Word8'
     In the second argument of `readData', namely
         `(extractInt ((L.unpack p)))'
     In a stmt of a 'do' expression:
         readData h (extractInt ((L.unpack p)))
     In the expression:
         do { h <- connectTo a (PortNumber p);
              hSetBuffering h NoBuffering;
              L.hPut h (encode (4205903872 :: Word32));
              p <- L.hGet h 8;
              .... }

I read this as saying that readData was expecting an Int, but instead  
extractInt returned it a Word8.  How do I fix extractInt to return an Int  
rather than a Word8?  Or is my problem something else?

Some other things that bother me is my repeating use of 'do'.  How can I  
go about breaking these functions out of being monadic and instead being  
pure?  Is that something I should be striving for, because otherwise I can  
see every function I write here being in a 'do' block.  Also, the final  
line of readFromStream bothers me.  I feel like I'm starting to violate  
some similar form of the Lay of Demeter.  (spelling?)  I don't like  
writing code that looks like "f1 (f2 (f3 (f4 (f5 e))))" even if that is  
what is officially going on, as a programmer I'd rather see named  
variables.  How can I fix that inside of a 'do' block?

Sorry, this is a bit of a brain dump, but I would really appreciate  
someone else's opinion.

Many thanks,

Tom


-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/


More information about the Beginners mailing list