Clojure中的循环定义

时间:2015-04-17 20:18:55

标签: clojure

以下是一个例子:

(defn f1 [] (lazy-seq (cons 0 (f2))))
(defn f2 [] (lazy-seq (cons 1 (f3))))
(defn f3 [] (lazy-seq (cons 2 (f1))))

在Haskell中,相当于上面的例子会产生一个懒惰的序列[0,1,2,0,1,2,...],但是在clojure中这会导致CompilerException,因为{{1}无法解决。

有什么方法吗?

2 个答案:

答案 0 :(得分:8)

使用declare创建转发声明

user> (declare f1) 
#'user/f1
user> (declare f2)
#'user/f2
user> (declare f3)
#'user/f3

或缩略图指出:

user> (declare f1 f2 f3)
#'user/f3

也适用

user> (defn f1 [] (lazy-seq (cons 0 (f2))))
#'user/f1
user> (defn f2 [] (lazy-seq (cons 1 (f3))))
 #'user/f2
user> (defn f3 [] (lazy-seq (cons 2 (f1))))
#'user/f3

然后你得到递归的懒惰序列:

user> (take 20 (f3))
(2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0)

答案 1 :(得分:8)

如果您只想生成延迟序列,可以使用letfn定义一组相互递归的函数 local

(letfn [(f1 [] (lazy-seq (cons 0 (f2))))
        (f2 [] (lazy-seq (cons 1 (f3))))
        (f3 [] (lazy-seq (cons 2 (f1))))]
  (f1))

=> (0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 ...