在我对Clojure For Comprehension 示例的回答中,我有一个处理自己的输出的函数:
(defn stream [seed]
(defn helper [slow]
(concat (map #(str (first slow) %) seed) (lazy-seq (helper (rest slow)))))
(declare delayed)
(let [slow (cons "" (lazy-seq delayed))]
(def delayed (helper slow))
delayed))
(take 25 (stream ["a" "b" "c"]))
("a" "b" "c" "aa" "ab" "ac" "ba" "bb" "bc" "ca" "cb" "cc" "aaa" "aab" "aac"
"aba" "abb" "abc" "aca" "acb" "acc" "baa" "bab" "bac" "bba")
它通过创建一个前向引用 ( delayed
) 来工作,该引用用作惰性序列 ( slow
) 中的第二个条目。该序列被传递给惰性函数,然后该函数的输出(惰性序列的第一部分,不需要评估delayed
)然后用于设置 的值delayed
。
这样我就“打结”了。但这在 Haskell 中做得更优雅(例如“打结”的解释</a>)。鉴于 Clojure 有delay
and force
,我想知道是否有更好的方法来完成上述操作?
delayed
那么问题是:在上面的代码中是否可以以某种方式避免(丑陋的,显式的)突变(of )?显然(?)你仍然需要突变,但它可以被“惰性”结构隐藏吗?
[昨晚我还在试图理解如何做到这一点时,遇到了一个类似标题的问题;在上面的代码运行之前没有人回复,所以我删除了它,但我对这种方法并不满意,所以我再试一次。]
另请参阅:Clojure 循环数据结构是否必须涉及 ref 之类的构造?(有点令人沮丧的是人们在重复问题)。