2010-03-09 5 views
3

Vous tentez d'utiliser Data.Binary.Get et ByteString et de ne pas comprendre ce qui se passe. Mon code est ci-dessous:Haskell ByteString/Data.Binary.Get question

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

Je reçois l'erreur suivante contre le troisième élément du tuple de retour, à savoir la charge utile:

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

Quelqu'un s'il vous plaît me expliquer l'interaction entre Data.Binary.Get et ByteStrings et comment je peux faire ce que j'ai l'intention de faire. Merci.

Répondre

1

Il existe deux types de données ByteString: l'un est en Data.ByteString.Lazy et l'autre en Data.ByteString.

Étant donné le L qualifiant votre ByteString, je présume que vous voulez la variété paresseuse, mais getByteString vous donne un ByteString strict.

Lazy ByteString s sont représentés en interne par une liste de ByteString s strictes.

Heureusement Data.ByteString.Lazy vous donne un mécanisme pour transformer une liste de ByteString s en ByteString paresseux.

Si vous définissez

import qualified Data.ByteString as S 


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

vous pouvez changer votre fragment de code à

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

et tous devraient être bien dans le monde.

+1

Vous n'avez pas besoin de convertir en une ByteString paresseuse - il vous suffit de l'obtenir directement via 'getLazyByteString'. Les docs haddock sont super. –

+0

Cela fonctionne aussi. =) –

+0

Tout à fait vrai dans ce cas. Il est à noter que c'est une opération distinctement différente. L'utilisation de 'getByteString' quand elle n'est pas nécessaire va forcer le' seglen' entier des octets tandis que 'getLazyByteString' restera paresseux. Peut-être que ce n'est pas important lorsque la taille maximale est de 64 Ko, mais si c'était un 'getWord32be', alors vous voudriez probablement le comportement paresseux au lieu de forcer potentiellement une allocation de 32 Go. –

5

Il dit que vous attendez le deuxième élément du tuple d'être un L.ByteString (je suppose que L est de Data.ByteString.Lazy), mais la routine retourne getByteString une ByteString stricte de Data.ByteString. Vous voulez probablement utiliser getLazyByteString.