Come convertire la sequenza lazy in non-pigro in Clojure

Ho provato quanto segue in Clojure, aspettandomi di restituire la class 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 restituisce la sequenza originale in quanto è ancora utile per la memoizzazione.

Allora, qual è il mezzo idiomatico di creare una sequenza non pigra da una pigra?

doall è tutto ciò di cui hai bisogno. Solo perché il seq ha tipo LazySeq non significa che sia in attesa di valutazione. Seq pigri memorizzano i loro risultati, quindi tutto ciò che devi fare è camminare una volta il pigro seq (come fa tutto il resto) per forzare tutto e renderlo così non pigro. seq non impone la valutazione dell’intera collezione.

Questa è in una certa misura una questione di tassonomia. una sequenza lenta è solo un tipo di sequenza come una lista, un vettore o una mappa. Quindi la risposta è ovviamente “dipende da quale tipo di sequenza non pigra vuoi ottenere:
Fai la tua scelta da:

  • una sequenza lazy ex-pigra (completamente valutata) (doall ... )
  • una lista per l’accesso sequenziale (apply list (my-lazy-seq)) OR (into () ...)
  • un vettore per l’accesso casuale successivo (vec (my-lazy-seq))
  • una mappa o un set se hai qualche scopo speciale.

Puoi avere qualunque tipo di sequenza più adatta alle tue esigenze.

Questo ragazzo ricco sembra conoscere il suo clojure ed ha assolutamente ragione.
Credo che questo snippet 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 il tipo non è cambiato ma la realizzazione ha

Mi sono imbattuto in questo post sul blog su doall non essere ricorsivo. Per quello ho trovato che il primo commento nel post ha fatto il trucco. Qualcosa sulla falsariga di:

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

Ho trovato questo utile in un test di unità in cui volevo forzare la valutazione di alcune applicazioni nidificate della map per forzare una condizione di errore.

 (.getClass (into '() (take 3 (repeatedly rand))))