查找第 n 个元素 - 函数组合

时间:2021-03-03 11:03:25

标签: clojure

我目前正在阅读“Clojure 的乐趣”一书,第 2 版。 在第 7 章“函数式编程”中,我遇到了以下用于描述函数组合的函数。

(defn fnth [n]
  (apply comp
         (cons first
               (take (dec n) (repeat rest)))))

((fnth 5) '[a b c d e])
;=> e

我不完全了解该函数的机制。 尝试在不使用 comp 的情况下重现内部作用域,该函数会生成一个重复列表:

(take (dec 5) (repeat (rest '[a b c d e])))
;=> ((b c d e) (b c d e) (b c d e) (b c d e))

使用 firstcomp 附加到重复列表有什么意义? 这也是输入 comp 的函数列表的最后一部分吗?

(first (take (dec 5) (repeat (rest '[a b c d e]))))
=> (b c d e)

先谢谢你!

2 个答案:

答案 0 :(得分:5)

fnth 函数的工作原理是构造 (first rest rest ... rest) 形式的序列,即 first 后跟 n - 1 rest s。然后通过 applying comp 将它们组合成一个函数。对于(fnth 5),这是

(apply comp (first rest rest rest rest))

当在向量 [a b c d e] 上调用结果函数时,结果应用程序是

(first (rest (rest (rest (rest [a b c d e])))))

即输入序列第 4 个尾部的第一个元素。

您尝试的重建只调用 rest 一次,然后 reapeat 返回返回的序列。

答案 1 :(得分:5)

这个 fnth 不(本身)返回集合的第 n 个项目,而是生成一个函数来这样做。

它应该产生什么函数来获得第一个项目?

(defn nth-1 [coll]
    (first coll))
    

它应该产生什么函数来获得第二个项目?

(defn nth-2 [coll]
    (first (rest coll)))
    

它应该产生什么函数来获得第三个项目?

(defn nth-3 [coll]
    (first (rest (rest coll))))
    

所以有一个模式!但是嵌套对于 fnth 来说是一个挑战。

(first (rest (rest x))) 的等效公式是 ((comp first rest rest) x)。现在我们可以将 nth-3 写成

(defn nth-3 [coll]
    ((comp first rest rest) coll))
    

使用这种方法 fnth 更容易编写。但是如果我们将 (comp first rest rest) 改写为 (apply comp [first rest rest]) 会更容易。那里!现在 fnth 需要列出第一个 + 正确数量的休息列表,并将 comp 应用到该列表。

相关问题