Saya mencoba yang berikut di Clojure, mengharapkan kelas dari urutan non-malas dikembalikan:
(.getClass (doall (take 3 (repeatedly rand))))
Namun, ini masih kembali clojure.lang.LazySeq
. Dugaan saya adalah itu doall
mengevaluasi seluruh urutan, tetapi mengembalikan urutan asli karena masih berguna untuk memoization.
Jadi apa cara idiomatik untuk membuat urutan non-malas dari urutan malas?
clojure
lazy-evaluation
Tim Clemons
sumber
sumber
doall
(vec (take 3 (repeatedly rand)))
Jawaban:
doall
adalah semua yang Anda butuhkan. Hanya karenaseq
memiliki tipeLazySeq
tidak berarti memiliki evaluasi tertunda. Lazyseq
s men-cache hasil mereka, jadi yang perlu Anda lakukan adalah menjalankan lazyseq
sekali (sepertidoall
halnya) untuk memaksakan semuanya, dan dengan demikian membuatnya tidak malas.seq
tidak tidak memaksa seluruh koleksi untuk dievaluasi.sumber
realized?
.realize
operasi yang cocokrealized?
.contains?
tidak peduli apakah Anda menyadari lazy seq atau tidak, ini menjawab pertanyaan spesifik seperti yang ditanyakan, tetapi kurang begitu untuk judul pertanyaan.Ini sampai taraf tertentu merupakan pertanyaan tentang taksonomi. urutan malas hanyalah salah satu jenis urutan seperti daftar, vektor atau peta. Jadi jawabannya tentu saja "itu tergantung pada jenis urutan non lazy apa yang ingin Anda dapatkan:
Pilih dari:
(doall ... )
(apply list (my-lazy-seq)) OR (into () ...)
(vec (my-lazy-seq))
Anda dapat memiliki jenis urutan apa pun yang paling sesuai dengan kebutuhan Anda.
sumber
(vec (my-lazy-seq))
tidak begitu baik dalam situasi seperti berikut:(vec (json/parse-string "{\"foo\":\"bar\"}")) ;; => [["foo" "bar"]]
Sejakcheshire
memilih untuk menghasilkan seq-malas dari(json/parse-string)
(json/parse-string-strict)
Orang kaya ini sepertinya tahu jubahnya dan benar sekali.
Namun, menurut saya cuplikan kode ini, dengan menggunakan contoh Anda, dapat menjadi pelengkap yang berguna untuk pertanyaan ini:
Memang jenisnya tidak berubah tapi realisasinya sudah
sumber
realized?
kembalitrue
. Misalnya(let [r (range) r? (realized? r)] (doall (take 1 r)) [r? (realized? r)]) => [false true]
[true true]
Saya tersandung pada posting blog ini tentang
doall
tidak rekursif. Untuk itu saya menemukan komentar pertama di posting melakukan trik. Sesuatu di sepanjang baris:Saya menemukan ini berguna dalam pengujian unit di mana saya ingin memaksa evaluasi beberapa aplikasi bersarang
map
untuk memaksa kondisi kesalahan.sumber
sumber