17

我希望压缩我的应用程序的网络流量。

根据(最新?)“Haskell 流行度排名”zlib似乎是一个非常流行的解决方案。zlib的接口使用ByteStrings:

compress :: ByteString -> ByteString
decompress :: ByteString -> ByteString

我正在使用常规Strings,它们也是 、 和 使用的read数据show类型Network.Socket

sendTo :: Socket -> String -> SockAddr -> IO Int
recvFrom :: Socket -> Int -> IO (String, Int, SockAddr)

所以要压缩我的字符串,我需要一些方法来将 a 转换String为 a ByteString,反之亦然。在hoogle的帮助下,我发现:

Data.ByteString.Char8 pack :: String -> ByteString

尝试使用它:

Prelude Codec.Compression.Zlib Data.ByteString.Char8> compress (pack "boo")

<interactive>:1:10:
    Couldn't match expected type `Data.ByteString.Lazy.Internal.ByteString'
           against inferred type `ByteString'
    In the first argument of `compress', namely `(pack "boo")'
    In the expression: compress (pack "boo")
In the definition of `it': it = compress (pack "boo")

失败,因为 (?) 有不同类型的ByteString?

所以基本上:

  • 有几种类型ByteString?有哪些类型,为什么?
  • String将s转换为 s 的“方法”是ByteString什么?

顺便说一句,我发现它确实适用于Data.ByteString.Lazy.Char8's ByteString,但我仍然很感兴趣。

4

3 回答 3

10

有两种字节串:严格(在Data.Bytestring.Internal中定义)和惰性(在Data.Bytestring.Lazy.Internal中定义)。正如您所发现的,zlib 使用惰性字节串。

于 2009-09-20T20:58:51.223 回答
8

您正在寻找的功能是:

import Data.ByteString as BS
import Data.ByteString.Lazy as LBS

lazyToStrictBS :: LBS.ByteString -> BS.ByteString
lazyToStrictBS x = BS.concat $ LBS.toChunks x

我希望它可以在没有 x 的情况下写得更简洁。(即无积分,但我是 Haskell 的新手。)

于 2012-06-15T14:53:53.340 回答
6

一个更有效的机制可能是切换到一个完整的基于字节串的层:

  • network.bytestring 用于字节串套接字
  • 用于压缩的惰性字节串
  • bytestring-show 的二进制文件替换 Show/Read
于 2009-09-20T19:41:13.547 回答