Ответ 1
Существует два типа байтов: строгий (определенный в Data.Bytestring.Internal) и ленивый (определенный в Data.Bytestring.Lazy.Internal). zlib использует ленивые байты, как вы обнаружили.
Я хочу сжать сетевой трафик приложения.
В соответствии с (последним?) Рейтинг популярности Haskell zlib кажется довольно популярным решением. Интерфейс zlib использует ByteString
s:
compress :: ByteString -> ByteString
decompress :: ByteString -> ByteString
Я использую регулярные String
s, которые также являются типами данных, используемыми read
, show
и Network.Socket
:
sendTo :: Socket -> String -> SockAddr -> IO Int
recvFrom :: Socket -> Int -> IO (String, Int, SockAddr)
Итак, чтобы сжать мои строки, мне нужно каким-то образом преобразовать String
в ByteString
и наоборот.
С помощью hoogle help:
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
в ByteString
s?Btw, я обнаружил, что он работает с Data.ByteString.Lazy.Char8
ByteString
, но я все еще заинтригован.
Существует два типа байтов: строгий (определенный в Data.Bytestring.Internal) и ленивый (определенный в Data.Bytestring.Lazy.Internal). zlib использует ленивые байты, как вы обнаружили.
Функция, которую вы ищете, это:
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.)
Более эффективным механизмом может быть переход на полный уровень на основе байтов: