我自己做一个功能

时间:2018-12-28 21:14:40

标签: clojure

我正在尝试自己创建一个take函数,但这似乎给堆栈带来了溢出,不知道是什么原因导致的?

(defn my-take-plus [n Lst LstAcc count]
  (let [LstVec (into [] Lst)]
    (cond (= count n) LstAcc
    :else 
      (do
         (conj LstAcc (first LstVec))
         (inc count)
         (my-take-plus n (apply list(rest LstVec)) LstAcc count)
      )
   )
 )
)


(defn my-take [n Lst]
  (my-take-plus n Lst [] 0)
)

2 个答案:

答案 0 :(得分:1)

此外,还有另一种“ clojurish”方式可以做到这一点:

(defn my-take [n data]
  (when (and (pos? n) (seq data))
    (lazy-seq
     (cons (first data)
           (my-take (dec n) (rest data))))))

这是个懒惰,还可以防止堆栈溢出。此外,据我所知,clojure.core/take的实现方式与此类似

答案 1 :(得分:0)

我会考虑使用loop/recur策略,以便Clojure进行尾部调用优化(TCO)以防止堆栈溢出。

(defn take' [n coll]
      (loop [n    n
             acc  []
             coll coll]
        (cond
          (empty? coll) acc
          ((comp not pos?) n) acc
          :else (recur (dec n) (conj acc (first coll)) (rest coll)))))

在您的示例中,我将考虑使用if,因为您只需要条件分支即可。 cond通常更像是case语句。