Clojure递归和一个懒惰的序列

时间:2011-12-13 21:34:28

标签: clojure

好的,我有点卡在这一点上,我真的可以做我正在尝试用下面的代码部分做的事情:

(recur (conj (get-links (first links)) (rest links))))

get-links返回一系列url,这些url被送入初始进程 - links调用然后应该递归。

我输入的第一个链接有效,但是我试图将一个序列连接到另一个链接的第二个链接给出了以下错误。

"Clojure.lang.LazySeq@xxxxxxx"

现在我想知道,这是否与生成未评估序列的“休息”(其余链接)的指令相关联?

(defn process-links
  [links]
  (if (not (empty? links))
    (do
      (if (not (is-working (first links)))
        (do
          (println (str (first links) " is not working"))
          (recur (rest links)))
        (do
          (println (str (first links) " is working"))
          (recur (conj (get-links (first links)) (rest links))))))))

如果我对此采取的方法完全错误,请告诉我。

2 个答案:

答案 0 :(得分:7)

conj将一个项目添加到集合中。在两个集合上使用它会创建一个嵌套结构。你可能想要concat这两个序列。

举例说明:

user> (conj [1 2 3] [4 5 6])
[1 2 3 [4 5 6]]
user> (concat [1 2 3] [4 5 6])
(1 2 3 4 5 6)

答案 1 :(得分:1)

关于“Clojure.lang.LazySeq@xxxxxxx”的事情:

问题在于此片段:

(println (str (first links) " is working"))

在这里,您使用字符串连接函数str(first links)(在这种情况下不是字符串)和" is working"(这是一个字符串)粘合在一起。 str对非字符串参数做了什么?它会调用.toString方法。 .toString对Clojure数据做了什么?并不总是你想要的东西。

解决方案是使用pr系列函数。 pr以一种被clojure读者识别的方式将Clojure数据写入流中。有关如何重写上述剪辑的两个示例:

(do (pr (first links))
    (println " is working"))

;; Sligtly less efficient since a string must be created
(println (pr-str (first links)) "is working")

请注意,如果您为println提供多个参数,则会打印所有中间有空格的项目。