必须Clojure循环数据结构涉及像ref这样的结构吗?

oct*_*bus 5 clojure circular-buffer

今天我看到了一些关于打结和循环数据结构的参考.我一直在读一些答案,解决方案似乎涉及使用ref指向列表的头部.一个特别的SO问题显示了一个Haskell示例,但我不知道Haskell是否足以知道该示例是否使用了与参数的Haskell等效.

有没有办法在不使用ref或类似构造的情况下使Clojure数据结构循环?

谢谢.

tno*_*oda 6

我直接将Haskell示例翻译成了Clojure:

user> (def alternates
          (letfn [(x [] (lazy-seq (cons 0 (y))))
                  (y [] (lazy-seq (cons 1 (x))))]
            (x)))
#'user/alternates
user> (take 7 alternates)
(0 1 0 1 0 1 0)
Run Code Online (Sandbox Code Playgroud)

它按预期工作.但是,我更喜欢使用以下cycle函数来相互递归函数letfn:

user> (take 7 (cycle [0 1]))
(0 1 0 1 0 1 0)
Run Code Online (Sandbox Code Playgroud)


mik*_*era 5

使用标准Clojure不可变数据结构和标准Clojure函数创建循环引用是不可能的.这是因为无法将第二个创建的对象添加到首先创建的(不可变)对象中.

但是,如果您愿意使用一些技巧,有多种方法可以创建循环数据结构:

  • 参考,原子等
  • 可变的deftypes
  • Java对象
  • 反思诡计
  • 懒惰的序列

但是,一般而言,在Clojure中最好避免使用循环数据结构.