me2
me2

Reputation: 754

Haskell ByteString / Data.Binary.Get question

Attempting to use Data.Binary.Get and ByteString and not understanding what's happening. My code is below:

getSegmentParams :: Get (Int, L.ByteString)
getSegmentParams = do 
    seglen <- liftM fromIntegral getWord16be
    params <- getByteString (seglen - 2)
    return (seglen, params)

I get the following error against the third item of the return tuple, ie payload:

Couldn't match expected type `L.ByteString'
       against inferred type `bytestring-0.9.1.4:Data.ByteString.Internal.ByteString'

Someone please explain to me the interaction between Data.Binary.Get and ByteStrings and how I can do what I'm intending. Thanks.

Upvotes: 3

Views: 1366

Answers (2)

Thomas M. DuBuisson
Thomas M. DuBuisson

Reputation: 64740

It says you expect the second element of the tuple to be a L.ByteString (I assume that L is from Data.ByteString.Lazy) but the getByteString routine returns a strict ByteString from Data.ByteString. You probably want to use getLazyByteString.

Upvotes: 5

Edward Kmett
Edward Kmett

Reputation: 29962

There are two ByteString data types: one is in Data.ByteString.Lazy and one is in Data.ByteString.

Given the L qualifying your ByteString, I presume you want the lazy variety, but getByteString is giving you a strict ByteString.

Lazy ByteStrings are internally represented by a list of strict ByteStrings.

Fortunately Data.ByteString.Lazy gives you a mechanism for turning a list of strict ByteStrings into a lazy ByteString.

If you define

import qualified Data.ByteString as S


strictToLazy :: S.ByteString -> L.ByteString
strictToLazy = L.fromChunks . return 

you can change your code fragment to

getSegmentParams :: Get (Int, L.ByteString)
getSegmentParams = do 
    seglen <- liftM fromIntegral getWord16be
    params <- getByteString (seglen - 2)
    return (seglen, strictToLazy params)

and all should be right with the world.

Upvotes: 1

Related Questions