- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个产生惰性序列的函数,称为 a 函数。
如果我运行代码:
(map a-function a-sequence-of-values)
(mapcat a-function a-sequence-of-values)
(apply concat (map a-function a-sequence-of-values))
(defn my-mapcat
[f coll]
(lazy-seq
(if (not-empty coll)
(concat
(f (first coll))
(my-mapcat f (rest coll))))))
最佳答案
延迟序列的生产和消费不同于延迟评估。
Clojure 函数对其参数进行严格/急切的评估。对产生或产生惰性序列的参数的评估不会强制实现产生的惰性序列本身。但是,任何由参数求值引起的副作用都会发生。mapcat
的普通用例是连接没有副作用的序列。因此,急切地评估某些论点并不重要,因为预期不会产生副作用。
您的职能 my-mapcat
通过将它们包装在 thunk(其他惰性序列)中,对其参数的评估施加额外的惰性。这在预期会产生显着副作用(IO、显着内存消耗、状态更新)时非常有用。但是,如果您的函数正在产生副作用并产生要连接的序列,您的代码可能需要重构,那么警告铃声可能会在您的脑海中响起。
这里与 algo.monads 类似
(defn- flatten*
"Like #(apply concat %), but fully lazy: it evaluates each sublist
only when it is needed."
[ss]
(lazy-seq
(when-let [s (seq ss)]
(concat (first s) (flatten* (rest s))))))
my-mapcat
:
(defn my-mapcat [f coll] (for [x coll, fx (f x)] fx))
(defn count-realized [s]
(loop [s s, n 0]
(if (instance? clojure.lang.IPending s)
(if (and (realized? s) (seq s))
(recur (rest s) (inc n))
n)
(if (seq s)
(recur (rest s) (inc n))
n))))
(let [seq-of-seqs (map range (list 1 2 3 4 5 6))
concat-seq (apply concat seq-of-seqs)]
(println "seq-of-seqs: " (count-realized seq-of-seqs))
(println "concat-seq: " (count-realized concat-seq))
(println "seqs-in-seq: " (mapv count-realized seq-of-seqs)))
;=> seq-of-seqs: 4
; concat-seq: 0
; seqs-in-seq: [0 0 0 0 0 0]
concat
适用的arity重载版本接受 4 个参数
[x y & xs]
(计算
&
)。
(let [seq-of-seqs (map range (list 1 2 3 4 5 6))
foo-seq (apply (fn foo [& more] more) seq-of-seqs)]
(println "seq-of-seqs: " (count-realized seq-of-seqs))
(println "seqs-in-seq: " (mapv count-realized seq-of-seqs)))
;=> seq-of-seqs: 2
; seqs-in-seq: [0 0 0 0 0 0]
(let [seq-of-seqs (map range (list 1 2 3 4 5 6))
foo-seq (apply (fn foo [a b c & more] more) seq-of-seqs)]
(println "seq-of-seqs: " (count-realized seq-of-seqs))
(println "seqs-in-seq: " (mapv count-realized seq-of-seqs)))
;=> seq-of-seqs: 5
; seqs-in-seq: [0 0 0 0 0 0]
(defn f [n] (println "foo!") (repeat n n))
user=> (def x (concat (f 1) (f 2)))
foo!
foo!
#'user/x
user=> (count-realized x)
0
lazy-cat
宏来防止这种情况
user=> (def y (lazy-cat (f 1) (f 2)))
#'user/y
user=> (count-realized y)
0
user=> (dorun y)
foo!
foo!
nil
user=> (count-realized y)
3
user=> y
(1 2 2)
apply
一个宏。
关于clojure - mapcat 打破懒惰,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21943577/
我有一个产生惰性序列的函数,称为 a 函数。 如果我运行代码: (map a-function a-sequence-of-values) 它按预期返回一个惰性序列。 但是当我运行代码时: (mapc
我对 Clojure 真的很陌生! `mapcat 如何工作? 最佳答案 mapcat function只是申请concat function的快捷方式结果为 map function : => (m
为了更好地理解mapcat,我举了一个例子: user> (mapcat #(list % %) [1 2 3]) (1 1 2 2 3 3) 并试图重现文档描述的内容,故意使用 map 和 con
在 Clojure 中有一个名为 mapcat 的函数在 Clojure 中,它与 flatmap in Scala 有一些相似之处.是used to map a function to a list
我是一名优秀的程序员,十分优秀!