Haskell ByteString/Data.Binary.Get问题

Haskell ByteString/Data.Binary.Get问题,haskell,bytestring,Haskell,Bytestring,试图使用Data.Binary.Get和ByteString,但不了解发生了什么。我的代码如下: getSegmentParams :: Get (Int, L.ByteString) getSegmentParams = do seglen <- liftM fromIntegral getWord16be params <- getByteString (seglen - 2) return (seglen, params) 请有人向我解释Data.B

试图使用Data.Binary.Get和ByteString,但不了解发生了什么。我的代码如下:

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

请有人向我解释Data.Binary.Get和bytestring之间的交互,以及我如何实现我的意图。谢谢。

有两种
ByteString
数据类型:一种在
data.ByteString.Lazy
中,另一种在
data.ByteString

考虑到
L
对ByteString进行了限定,我认为您需要惰性类型,但是
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)
getSegmentParams::Get(Int,L.ByteString)
getSegmentParams=do

seglen它说您希望元组的第二个元素是
L.ByteString
(我假设L来自
Data.ByteString.Lazy
),但是
getByteString
例程从
Data.ByteString
返回严格的ByteString。您可能想使用
getLazyByteString

您不需要转换为惰性的ByteString,只需通过
getLazyByteString
直接获取一个即可。黑线鳕的文档很棒,在这种情况下非常正确。值得注意的是,这是一个截然不同的操作。在不需要时使用
getByteString
将强制执行整个
seglen
字节,而
getLazyByteString
将保持惰性。当最大大小为64kB时,这可能并不重要,但是如果这是
getWord32be
的话,那么您可能希望使用惰性行为,而不是强制执行32GB的分配。
getSegmentParams :: Get (Int, L.ByteString)
getSegmentParams = do 
    seglen <- liftM fromIntegral getWord16be
    params <- getByteString (seglen - 2)
    return (seglen, strictToLazy params)