查找第n个元素-函数组合
我目前正在阅读“Clojure 的乐趣”一书,第二版。在第 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))
first使用附加到该重复列表有comp什么意义?这也是输入的函数列表的最后一部分comp吗?
(first (take (dec 5) (repeat (rest '[a b c d e]))))
=> (b c d e)
先感谢您!
回答
该fnth函数的工作原理是构造一个形式为(first rest rest ... rest)iefirst后跟 n - 1 rests的序列。然后它通过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返回返回的序列。
回答
这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 应用于该列表。