2015-07-22 12 views
6

Sto provando a leggere e scrivere moltissimi ints nella memoria costante. Ho capito come scrivere gli interi in memoria, ma non ho capito come leggerli.Utilizzo di pipe per leggere e scrivere dati binari in Haskell

import Control.Lens (zoom) 
import System.IO (IOMode(..), withFile) 
import Pipes 
import qualified Pipes.Prelude as P 
import qualified Pipes.ByteString as PB  
import qualified Pipes.Parse as P 
import qualified Pipes.Binary as P 

intStream :: Monad m => Proxy x' x() Int m b 
intStream = go (0 :: Int) where 
    go i = yield i >> go (i + 1) 

decoder :: Monad m => Int -> P.Parser P.ByteString m [Int] 
decoder n = zoom (P.decoded . P.splitAt n) P.drawAll 

main :: IO() 
main = do 
    withFile "ints" WriteMode $ \h -> do 
     runEffect $ for intStream P.encode >-> P.take 10000 >-> PB.toHandle h 
    withFile "ints" ReadMode $ \h -> do 
     xs <- P.evalStateT (decoder 10000000) (PB.fromHandle h) 
     print xs 

ho avuto la funzione di decoder dalla documentazione per Pipes.Binary. Tuttavia usa drawAll che secondo lo documentationdrawAll non è un uso idiomatico di Pipes e viene fornito a scopo di test.

La mia domanda è come modificare decoder in modo che non usi drawAll e quindi non carichi tutti i valori di xs in memoria. Quindi, invece di stampare l'elenco di xs, potevo su un flusso di decodificato ints letto dal file.

risposta

6

I documenti dicono che decoded è un obiettivo da un flusso di byte a un flusso di valori decodificati. Siamo in grado di ottenere il secondo dalla ristrutturazione dell'ex utilizzando view da lens:

decoder :: Monad m => Int -> Producer P.ByteString m a -> Producer Int m() 
decoder n p = void (view P.decoded p) >-> P.take n 

main :: IO() 
main = do 
    withFile "ints" WriteMode $ \h -> do 
     runEffect $ for intStream P.encode >-> P.take 10000 >-> PB.toHandle h 
    withFile "ints" ReadMode $ \h -> do 
     runEffect $ decoder 10000 (PB.fromHandle h) >-> P.print 

non ho molta esperienza con pipes, ho solo seguito le tipologie qui. Il programma sembra funzionare come previsto.

+0

Provo a seguire i tipi ma a volte diventa difficile quando i tipi iniziano a sembrare zuppa alfabetica;) –

Problemi correlati