Clojure返回列表

时间:2016-02-10 20:00:43

标签: clojure

我知道这个例子很简单,因为我认为有一个clojure库函数可以做到这一点,这不是重点。

我有以下代码

(defn makelistres [a b res]
  (if (= a b) res (makelistres a (dec b) (conj res b))))

(defn makelist [a b]
  (makelistres a b [])
)

有没有办法在不必将列表作为参数传递的情况下执行相同的效果?比如把它扔到堆栈上

(defn test [a b]
  (if (= a b) 0 (+ 1 (test a (dec b))))
)

不知道括号是否匹配,就像我在这个文本框中写的那样,但你明白了。

2 个答案:

答案 0 :(得分:4)

是否可以向函数添加一个arity,然后使用其他arg(空向量)调用该函数?

像这样:

(defn makelist
  ([a b] (makelist a b []))
  ([a b res]
    (if (== a b) res (makelist a (dec b) (conj res b)))))

在repl中:

user> (makelist 1 10)
[10 9 8 7 6 5 4 3 2]

如果没有,loop将执行:

(defn makelist [a b]
  (loop [a a b b res []]
    (if (== a b)
      res
      (recur a (dec b) (conj res b)))))

或者像这样(因为a没有改变):

(defn makelist [a b]
  (loop [b b res []]
    (if (== a b)
      res
      (recur (dec b) (conj res b)))))

但是,有一个lib功能: (range 10 1 -1)

答案 1 :(得分:-2)

约翰

有几种方法:

<强> (def res [1,2,3,4,5])

然而,这需要在调用makelistres之前先对数据进行定义。有办法做到这一点。

<强> (def res-val (atom [])

使用基于原子的函数以编程方式设置和检索更灵活。然而;您正在使用可变(有状态)对象。你的意识形态可能会避开这个!

由于您要更改res的内容,atom方法似乎更适合。您基本上会设置res (using swap)makelistderefing (e.g. @res)项的值,或者在makelistres的递归中修改它。