2013-04-20 12 views
6

Dlaczego Data.Binary.Get nie jest leniwy, jak to mówi? Czy robię coś złego tutaj?Lazy binary get

import Data.ByteString.Lazy (pack) 
import Data.Binary.Get (runGet, isEmpty, getWord8) 

getWords = do 
    empty <- isEmpty 
    if empty 
    then return [] 
    else do 
     w <- getWord8 
     ws <- getWords 
     return $ w:ws 

main = print $ take 10 $ runGet getWords $ pack $ repeat 1 

Ta główna funkcja po prostu zawiesza się zamiast drukować 10 słów.

+0

Dokumentacja jesteś połączony mówi: „Ten dekoder ma wadę, że będzie trzeba czytać wszystkie wejścia, zanim będzie mogła wrócić” –

+0

@MikhailGlushenkov No cóż, jak to przegapiłem. Dzięki :) – swish

Odpowiedz

4

Dołączona dokumentacja zawiera kilka przykładów. Pierwszy musi przeczytać wszystkie dane wejściowe, zanim będzie mógł wrócić i wygląda podobnie do tego, co napisałeś. Drugi to składanie w lewo i przetwarza dane wejściowe w sposób strumieniowania. Oto twój kod przepisany w tym stylu:

module Main where 

import Data.Word (Word8) 
import qualified Data.ByteString.Lazy as BL 
import Data.Binary.Get (runGetState, getWord8) 

getWords :: BL.ByteString -> [Word8] 
getWords input 
    | BL.null input = [] 
    | otherwise = 
     let (w, rest, _) = runGetState getWord8 input 0 
     in w : getWords rest 

main :: IO() 
main = print . take 10 . getWords . BL.pack . repeat $ 1 

Testowanie:

*Main> :main 
[1,1,1,1,1,1,1,1,1,1]