[Haskell-beginners] Extract and integer from a ByteString
Stephen Tetley
stephen.tetley at gmail.com
Wed Jun 16 06:18:28 EDT 2010
On 16 June 2010 08:40, Tom Hobbs <tvhobbs at googlemail.com> wrote:
> Hi Stephen,
>
> Thanks for the answer, I shall give it a go later tonight (UK time).
> Why would I want to keep my functions monadic? It's not that I'm against
> the idea, rather it's that I don't understand the choice. I was under the
> (possibly wrong) impression that (IO) monadic functions were just to "get
> around" the issue of side-effects and that where possible functions should
> be coded outside of monads. Is that just plain wrong, or does it boil down
> to "It depends on what you're doing, and in this case..."?
Hi Tom
Yes - its a "depend on what your doing" thing...
For reading binary data, having a set of functions to read different
types of data provides a nice interface. Data.Binary.Get provides some
- e.g. getWord8, getWord32,... - and they are all in the Get monad.
For a particular domain you would want to
construct the parsers for that domain - but still keep them in the Get
monad so you would keep the uniform interface.
E.g., say if you had a structure for IP address, stored without the dots:
data IPAddr = IPAddr Word8 Word8 Word8 Word8
getIPAddr :: Get IPAddr
getIPAdde = do
{ a <- getWord8
; b <- getWord8
; c <- getWord8
; d <- getWord8
; return (IPAddr a b c d)
}
In you original code, the extractInt function is a good candidate to
be a "Get" function rather than a a function that turns [Word8] data
into an Int - i.e. I would make it do some parsing work rather than
just the data conversion. As you are always reading 4 bytes and its
big endian (I think?), I would adapt the existing getWord32be parser:
extractInt :: Get Int
extractInt = do
{ a <- getWord32be
; return (fromIntegral a)
}
Or more succinctly:
extractInt :: Get Int
extractInt = liftM fromIntegral getWord32be
liftM, liftM2 are a family of functions that post-process the value
(or values) returned from monadic operation(s) with a pure function
(here fromIntegral).
Of course, this will mean that the other code will have to be changed
to use Data.Binary.Get but the end result should be cleaner code.
> Also I think I've already encountered the hidden Data.Binary problem in GHC.
> I have got around it already by (if memory serves) starting GHC and telling
> it to ignore it's own Data.Binary so I can then include it in my own
> projects. But I created an alias which starts this Data.Binary-capable GHC
> and I can't remember what's behind it now!
> What's the reason for GHC hiding packages and preventing them from being
> imported/used in loaded projects?
GHC used to ship with a lot of libraries, but that was a large
maintenance effort and now the Haskell Platform does this job.
However, GHC is self-contained, so it still ships versions of the
third-party libraries it uses internally (base, containers, the
cabal-libraries but not the "cabal install" the tool...). I think
Data.Binary is a more recent dependency, and its perhaps just an
accident that it is half in / half out.
Best wishes
Stephen
More information about the Beginners
mailing list