Ste*_*gle 15 list-comprehension clojure lazy-evaluation
(take 2 (for [x (range 10)
:let [_ (println x)]
:when (even? x)] x))
>> (* 0
* 1
* 2
* 3
* 4
* 5
* 6
* 7
* 8
* 9
0 2)
Run Code Online (Sandbox Code Playgroud)
我以为我只是非常密集.但不是,事实证明Clojure实际上评估了任何延迟序列的前32个元素(如果可用).哎哟.
我有一个for递归电话:let.我很好奇为什么计算似乎是先进行广泛而不是深度优先.似乎计算(尽管,公平,不是内存)正在爆炸,因为我一直在递归树的所有上部分支.虽然代码的逻辑意图是深度优先的,但Clojure的32分块正在强制进行广泛的第一次评估.
无论如何,有没有简单的方法来强制1分块而不是32分块的懒惰序列?
Cha*_*ffy 13
Michaes Fogus 撰写了一篇关于通过提供自定义ISeq实现来禁用此行为的博客条目.
从Colin Jones的修改版本中无耻地窃取:
(defn seq1 [#^clojure.lang.ISeq s]
(reify clojure.lang.ISeq
(first [_] (.first s))
(more [_] (seq1 (.more s)))
(next [_] (let [sn (.next s)] (and sn (seq1 sn))))
(seq [_] (let [ss (.seq s)] (and ss (seq1 ss))))
(count [_] (.count s))
(cons [_ o] (.cons s o))
(empty [_] (.empty s))
(equiv [_ o] (.equiv s o))))
Run Code Online (Sandbox Code Playgroud)
在"欢乐的Clojure"中给出了一种更简单的方法:
(defn seq1 [s]
(lazy-seq
(when-let [[x] (seq s)]
(cons x (seq1 (rest s))))))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1101 次 |
| 最近记录: |