Pregunta

Intenté lo siguiente en Clojure, esperando tener la clase de una secuencia no perezosa devuelta:

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

Sin embargo, esto todavía devuelve clojure.lang.LazySeq . Supongo que doall evalúa la secuencia completa, pero devuelve la secuencia original, ya que sigue siendo útil para la memorización.

Entonces, ¿cuál es el medio idiomático de crear una secuencia no perezosa a partir de una perezosa?

¿Fue útil?

Solución

doall es todo lo que necesitas. El hecho de que el seq tenga el tipo LazySeq no significa que tenga una evaluación pendiente. Las secuencias perezosas almacenan en caché sus resultados, por lo que todo lo que necesita hacer es recorrer la secuencia lenta una vez (como lo hace doall) para forzarlo todo y, por lo tanto, hacer que no sea perezoso. seq no obliga a evaluar toda la colección.

Otros consejos

Esta es, hasta cierto punto, una cuestión de taxonomía. una secuencia perezosa es solo un tipo de secuencia como lo es una lista, un vector o un mapa. Por lo tanto, la respuesta es, por supuesto, "depende del tipo de secuencia no perezosa que desee obtener:
Elija entre:

  • una secuencia perezosa ex-perezosa (totalmente evaluada) (doall ...)
  • una lista para acceso secuencial (aplicar lista (my-lazy-seq)) OR (into () ...)
  • un vector para acceso aleatorio posterior (vec (my-lazy-seq))
  • un mapa o un conjunto si tiene algún propósito especial.

Puede tener el tipo de secuencia que más se adapte a sus necesidades.

Este tipo rico parece conocer su posición y tiene toda la razón.
Pero creo que este fragmento de código, usando su ejemplo, podría ser un complemento útil para esta pregunta:

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

De hecho, tipo no ha cambiado pero realización

Me topé con esto en este blog publicación sobre doall que no es recursivo. Para eso encontré que el primer comentario en la publicación hizo el truco. Algo en la línea de:

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

Encontré esto útil en una prueba unitaria donde quería forzar la evaluación de algunas aplicaciones anidadas de map para forzar una condición de error.

(.getClass (into '() (take 3 (repeatedly rand))))
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top