用map做“foreach”风格的调用

时间:2012-07-31 21:15:35

标签: clojure

我正在努力学习Clojure的学习曲线,我正在编写一个简单的程序,它应该输出给定字符串的排列列表。我的递归解决方案会多次调用自身(因此有一个调用树而不是一维堆栈)。我试图理解,如果给出一个列表,我可以多次调用一个函数,从每个调用的列表中给它一个元素。我目前的代码是

(def permuteCat (
    fn [string printlist appendval]
    ( permute string (concat printlist (list appendval)) )
))

(def permuteRecurse (
    fn [string printlist appendlist]
    (
    map (partial permuteCat string printlist) appendlist
    )
))

(def permute (
    fn [string printlist] 
    (if ( == (count printlist) (.length string) )
        (println printlist)
        ( permuteRecurse string printlist ( range (- (.length string) (count printlist)) ) ) 
    )
)
)

然而看起来permuteCat()永远不会被permuteRecurse()调用。在像OCaml这样的语言中,我会使用地图运算符来调用permuteCat,但我知道Clojure本身并不支持currying。这样做的首选方法是什么?或者我只是偏离基础,需要采取完全不同的方法?

1 个答案:

答案 0 :(得分:0)

doseq是表示强制执行foreach的惯用方法。 map产生一个惰性序列,因此在使用序列之前不会执行任何操作。您可以使用doseq来编写命令式样式的foreach循环,但更好的方法是将序列的创建与您想要的序列分开(在这种情况下打印,但稍后您可能希望通过它进行搜索)。

; specify the sequence
(defn foo [v] (map inc v))

; print it
(doseq [v (foo [1 2 3])]
  (println v))