2010-03-25 9 views
9

Sto leggendo un flusso di dati di grandi dimensioni utilizzando i lazy bytestrings e voglio sapere se sono disponibili almeno X byte in più durante l'analisi. Cioè, voglio sapere se il bytestring è lungo almeno X byte.In Haskell, la durata della chiamata su Lazy ByteString forza l'intera stringa in memoria?

Chiamando lo length su di esso, l'intero flusso verrà caricato, quindi vanificando lo scopo di utilizzare il test automatico pigro?

In caso affermativo, il followup potrebbe essere: come sapere se ha almeno X byte senza caricare l'intero flusso?

MODIFICA: Inizialmente l'ho chiesto nel contesto della lettura dei file, ma ho capito che esistono modi migliori per determinare il file. La soluzione definitiva che mi serve, tuttavia, non dovrebbe dipendere dalla pigra fonte del test.

risposta

11

Sì.

length . take x.

+0

Grazie. Quindi la risposta è sì, usando la lunghezza si caricherà l'intera stringa in memoria? – me2

+0

Sì, la lunghezza imporrà l'intera lista e "carica: it. Quindi, la contromisura in forma di" take " – ADEpt

+1

Quindi, per essere chiari capiamo tutti, sì la lunghezza forzerà la stringa in memoria, quindi se chiami prendi x per prima cosa, almeno, stai forzando la memoria dei primi x byte. – MtnViewMark

1

C'è un motivo per cui non stai usando hFileSize :: Handle -> IO Integer per ottenere la lunghezza del file?

+0

Sì, perché l'input potrebbe non essere effettivamente un file, ma un flusso di rete. Non mi interessa la lunghezza effettiva dei dati, ma se ci sono dati sufficienti per rendere il contenuto valido (o troncato, nel qual caso i dati sono corrotti). – me2

+3

In tal caso non esiste alcun programma sulla Terra che possa trovare la lunghezza del flusso senza leggerlo fino alla fine. –

0

MODIFICA: ci dispiace. Immagino che stavo pensando che gli estensori fossero liste. Non esiste una lunghezza generica per i bytestrings.

length è rigoroso perché il tipo restituito Int è rigoroso. Puoi usare genericLength da Data.List e importare una libreria che definisce i numeri pigri di Peano e fornirti un'istanza Num per esempio, ad esempio la libreria numbers:

Ciò ti consente di esprimere la tua funzione nel modo che preferisci, ma la risposta di ephemient è funzionalmente la stessa e non richiede l'importazione di una nuova libreria.

Ho appena fatto un post sul blog su questo argomento qui, se questo suona come un approccio che potrebbe essere interessato a:

http://coder.bsimmons.name/blog/2010/03/lazy-arithmetic-in-haskell/

+0

ByteString non viene fornito con' genericLength' .Devi scriverne uno tu stesso. – kennytm

+0

Da qualche parte (probabilmente su Hackage, anche se non riesco a trovarlo ora) mi sono imbattuto in un tipo di numero naturale "frammentato", sulla falsariga di "dati Nat = Zero | Sum Integer Nat', che sarebbe probabilmente più efficiente della soluzione basata su 'take', probabilmente. –

0

Dovrà iterare l'intera stringa, ma se si don' t mantenere un riferimento all'intera stringa di byte pigro in qualsiasi altro punto, credo che dovrebbe essere in grado di liberare la testa della stringa mentre avanza verso la coda.

Problemi correlati