Domanda

Ho provato quanto segue in Clojure, aspettandomi di restituire la classe di una sequenza non pigra:

(.getClass (doall (take 3 (repeatedly rand))))

Tuttavia, questo restituisce ancora clojure.lang.LazySeq . La mia ipotesi è che doall valuti l'intera sequenza, ma restituisca la sequenza originale in quanto è ancora utile per la memoizzazione.

Quindi qual è il mezzo idiomatico per creare una sequenza non pigra da una pigra?

È stato utile?

Soluzione

doall è tutto ciò di cui hai bisogno. Solo perché il seq ha il tipo LazySeq non significa che ha una valutazione in sospeso. Seq pigri memorizzano nella cache i loro risultati, quindi tutto ciò che devi fare è camminare una volta sul pigro seq (come fa Doall) per forzare tutto e renderlo non pigro. seq non forza a valutare l'intera collezione.

Altri suggerimenti

Questa è in una certa misura una questione di tassonomia. una sequenza pigra è solo un tipo di sequenza come è un elenco, un vettore o una mappa. Quindi la risposta è ovviamente "dipende dal tipo di sequenza non pigra che vuoi ottenere:
Scegli tra:

  • una sequenza pigra ex-pigra (completamente valutata) (doall ...)
  • un elenco per l'accesso sequenziale (applica elenco (my-lazy-seq)) OPPURE (in () ...)
  • un vettore per un accesso casuale successivo (vec (my-lazy-seq))
  • una mappa o un set se hai uno scopo speciale.

Puoi avere qualunque tipo di sequenza la maggior parte delle suite di cui hai bisogno.

Questo Rich sembra conoscere il suo clojure ed ha assolutamente ragione.
Buth Penso che questo frammento di codice, usando il tuo esempio, potrebbe essere un utile complemento a questa domanda:

=> (realized? (take 3 (repeatedly rand))) 
false
=> (realized? (doall (take 3 (repeatedly rand)))) 
true

In effetti tipo non è cambiato ma realizzazione è

Mi sono imbattuto in questo blog post su doall non ricorsivo. Per quello che ho trovato il primo commento nel post ha fatto il trucco. Qualcosa del genere:

(use 'closure.walk)
(postwalk identity nested-lazy-thing)

L'ho trovato utile in un unit test in cui volevo forzare la valutazione di alcune applicazioni nidificate di map per forzare una condizione di errore.

(.getClass (into '() (take 3 (repeatedly rand))))
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top