【问题标题】:Haskell ByteString / Data.Binary.Get questionHaskell ByteString / Data.Binary.Get 问题
【发布时间】:2010-03-09 23:12:46
【问题描述】:

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

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 之间的交互,以及我可以如何做我想做的事情。谢谢。

【问题讨论】:

    标签: haskell bytestring


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      ByteString 数据类型有两种:一种在Data.ByteString.Lazy 中,一种在Data.ByteString 中。

      鉴于 L 限定了您的 ByteString,我认为您想要惰性变体,但 getByteString 给您一个严格的 ByteString

      惰性ByteStrings 在内部由严格的ByteStrings 列表表示。

      幸运的是Data.ByteString.Lazy 为您提供了一种机制,可以将严格的ByteStrings 列表转换为懒惰的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)
      

      世界上一切都应该是正确的。

      【讨论】:

      • 您不需要转换为惰性字节字符串 - 只需通过 getLazyByteString 直接获取一个。黑线鳕文档很棒。
      • 在这种情况下非常正确。值得注意的是,这是一个截然不同的操作。在不需要时使用getByteString 将强制使用整个seglen 字节,而getLazyByteString 将保持惰性。当最大大小为 64kB 时,这可能并不重要,但如果那是 getWord32be,那么您可能想要惰性行为而不是可能强制分配 32GB。
      猜你喜欢
      • 1970-01-01
      • 2013-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-03
      • 1970-01-01
      相关资源
      最近更新 更多