2010-03-09 62 views
3

試圖使用Data.Binary.Get和ByteString,而不理解發生了什麼。我的代碼如下:Haskell ByteString/Data.Binary.Get question

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

我得到對返回元組的第三項,即有效載荷以下錯誤:

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

有人請向我解釋Data.Binary.Get之間的相互作用ByteStrings以及我如何能夠做我想要的。謝謝。

回答

1

有兩個ByteString數據類型:一個在Data.ByteString.Lazy和一個在Data.ByteString

鑑於L預選賽你字節串,我想你想偷懶的品種,但getByteString是給你一個嚴格ByteString

懶惰ByteString s在內部由嚴格的ByteString s列表表示。

幸運的是Data.ByteString.Lazy爲您提供了將嚴格ByteString s的列表變爲惰性ByteString的機制。

如果定義

import qualified Data.ByteString as S 


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

你可以改變你的代碼片段

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

,並都應該是正確的與世界接軌。

+1

您不需要轉換爲Lazy ByteString - 只需通過getLazyByteString直接獲取一個即可。黑線鱈文檔非常棒。 – 2010-03-10 00:14:34

+0

也可以。 =) – 2010-03-10 13:55:16

+0

在這種情況下確實如此。值得注意的是這是一個截然不同的操作。不需要時使用'getByteString'會強制整個'seglen'字節,而'getLazyByteString'將保持惰性。也許這在最大大小爲64kB時並不重要,但如果這是'getWord32be',那麼您可能需要懶惰行爲而不是可能強制32GB分配。 – 2010-03-10 17:03:19

5

它說你所期望的元組的第二個元素是一個L.ByteString(我假設L爲Data.ByteString.Lazy),但getByteString例程返回嚴格從Data.ByteString字節字符串。您可能想要使用getLazyByteString