How can I define a function with uncertain argument in clojure

时间:2016-02-03 02:58:50

标签: clojure reduce

I am wondering how to define a function with an uncertain argument in clojure. Here is an example:

(reduce + [1 2 3 4]) => 10
(reduce list [1 2 3 4]) => (1 2 3 4)
(reduce inc [3]) => 3

I want to define the reduce function (reduce func coll) which can apply the func to the first two elements in coll, then apply the func to the result of the first two elements and the third element, until all the elements are used. I am puzzled that is it different with the source code of reduce? I have no idea how to define this function so far. Is there anyone can help me to figure out this problem or give me some tips? I will appreciate that!

2 个答案:

答案 0 :(得分:2)

要明确的是,你要求这样做:

  

将func应用于coll中的前两个元素,然后将func应用于前两个元素和第三个元素的结果,

这正是reduce的作用:

user> (reduce list [1 2 3 4])
(((1 2) 3) 4)

前两个列表是(1 2)。然后,将list函数应用于此结果和下一个元素3,然后获得((1 2) 3)。并继续,直到所有元素都用完为止。

我怀疑你没有正确或清楚地提出你的问题。

-

我现在看到你问的不是如何创建你想要的与reduce不同的功能,而是如何实际实现减少自己?

如果是这种情况,通常这样的功能设计涉及递归,您将序列分成头部和尾部,处理它,然后在尾部重复,然后将其再次分成头部和尾部,直到没有更多的尾巴。

答案 1 :(得分:1)

Might be good to contrast reduce with apply. Here's the best definition I could find for apply:

apply explodes a seqable data structure so it can be passed to a function that expects a rest parameter. For example, max takes any number of arguments and returns the greatest of all the arguments.

This definition comes from the 'Brave and True' book

reduce does not make sense with only one argument whereas apply works for any number of arguments - it applies all of the arguments to the function. Hence in your last example inc is given 3 and returns 4 if you use apply rather than reduce.

The function used with apply must take 'any' number of arguments, denoted by the a & in the formal parameters definition. So apply just grabs all values inside the sequence and gives them to the function. Actually apply is quite greedy with this 'grabbing' so what follows the function can in fact be a series of arguments not contained within a structure.

In a way reduce is stricter about the way it uses its function. The function must take two arguments (or none for an edge case) because that is how reduce uses it. The result of calling the function on the first two arguments is then passed to the third and so on, much as you described it in your question.

Edit A more comprehensive definition of apply