6

我正在通过 SICP 工作 - 一项练习是实施 foreach (doseq)。这是一个学术练习。在clojure中,这就是我想出的:

(defn for-each [proc, items]
  (if (empty? items) nil
      (do
        (proc (first items))
        (recur proc (rest items)))))

但是,我对是否do作弊有点模糊,因为do它是 clojure 中的一种特殊形式,我认为 SICP 中还没有引入类似的东西。有没有更简约的答案?

这是仅在最后一个元素上执行 proc 的另一种尝试:

(defn for-each-2 [proc, items]
  (let [f (first items)
        r (rest items)]
    (if (empty? r)
      (proc f)
      (recur proc r))))
4

2 回答 2

3

使用doseq,一切就绪。例如:

(doseq [e '(1 2 3)]
       (prn e))

将打印:

1
2
3
nil

编辑 :

如果您想for-each手动实现并使用尽可能少的特殊形式,这是另一种选择,尽管它最终几乎和您的一样短:

(defn for-each [f l]
  (cond (empty? l) nil
        :else (do (f (first l)) 
                  (recur f (rest l)))))

有趣的是,同样的过程可以在 SICP 中使用的 Lisp 方言 Scheme 中更简洁地编写:

(define (for-each f l)
  (cond ((null? l) null)
        (else (f (first l))
              (for-each f (rest l)))))
于 2012-02-26T19:12:38.790 回答
1

这是我的尝试。它只是在内部循环中执行函数。

(defn for-each [fun, xs]
  (loop [fun fun
         xs xs
         action nil]
    (if (first xs)
      (recur fun (rest xs) (fun (first xs)))
      xs)))
于 2012-02-26T20:45:30.430 回答