2010-03-09 2 views
3

Попытка использования Data.Binary.Get и ByteString и непонимание того, что происходит. Мой код ниже:Haskell ByteString/Data.Binary.Показать вопрос

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 квалифицирует ваш ByteString, я предполагаю, что вы хотите ленивого сорта, но getByteString дает вам строгую ByteString.

Lazy 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'. Документы пикши великолепны. –

+0

Это тоже работает. =) –

+0

Совершенно верно в этом случае. Стоит отметить, что это совершенно другая операция. Использование 'getByteString', когда оно не понадобится, заставит весь« seglen »байтов, в то время как' getLazyByteString' останется ленивым. Возможно, это неважно, когда максимальный размер составляет 64 КБ, но если это был 'getWord32be', тогда вам, скорее всего, понадобится ленивое поведение вместо потенциального форсирования 32 ГБ. –

5

Он говорит, что вы ожидаете, что второй элемент кортежа быть L.ByteString (я предполагаю, что L от Data.ByteString.Lazy), но getByteString процедуры возвращает строгая байтовой строкой из Data.ByteString. Вероятно, вы хотите использовать getLazyByteString.