doseq应该给我带来副作用,那为什么它只适用于dorun?

时间:2015-11-01 15:34:14

标签: clojure

我写了一个简单的程序,它以数字n和列表作为输入。然后打印列表中的每个元素n次。

我最初尝试过这个

(defn list-repl [num lst]
  (doseq [elem lst]
    (map println (repeat num elem))))

这没有用。没有输出。然后在查看文档时我发现了dorun。我试过这个并且它确实有效。

(defn list-repl [num lst]
  (doseq [elem lst]
    (dorun (map println (repeat num elem)))))

阅读文档我可以理解的是doseq就像一个循环结构,强制其身体表达的副作用。 dorun也直接为序列做到这一点。

这种理解是否正确?如果它是正确的那么第一个例子中的主体应该给我打印数字的副作用。但那并没有发生。那么我的理解中缺少什么?

1 个答案:

答案 0 :(得分:4)

基本上,doseq不能强迫身体产生任何副作用。为了保证它必须以递归方式检查其体内的每个表达式,以便强制执行惰性子计算,这将是......具有挑战性。它只处理顶级表达式。强制任何惰性子计算是表达式'writer的工作。

如果需要多层循环来“解包”外部序列的成员,请记住doseqfor和其他变体都通过提供多个绑定来支持嵌套循环:

(defn list-repl [num lst]
  (doseq [elem lst
          to-print (repeat num elem)]
    (println to-print)))