我发现以下代码(在解决this blog postCoin Changer Kata中):

(defn change-for [amount]
  (let [denominations [25 10 5 1]
        amounts (reductions #(rem %1 %2) amount denominations)
        coins (map #(int (/ %1 %2)) amounts denominations)]
    (mapcat #(take %1 (repeat %2)) coins denominations)))

我觉得困难的部分是:(reductions #(rem %1 %2) amount denominations)

正如我发现的那样,reductions只是基于某些给定的函数递增地计算结果集合。示例:(reductions + [1 2 3])给出[1 3 6]
1         ; first  element
1 + 2     ; second element
1 + 2 + 3 ; third  element

下一个函数rem用于计算余数,仍然非常简单易懂。

为了理解其余的代码,我尝试了以下操作:
; first try, to see if this call works
; outside the original code (the change-for function)
(reductions #(rem %1 %2) 17 [10 5 1]) ; --> [17 7 2 0]

; tried to use the reductions which takes only one argument
; notice that 17 is now inside the array
(reductions #(rem %1 %2) [17 10 5 1]) ; --> [17 7 2 0]

; further simplified the expression
(reductions rem [17 10 5 1]) ; --> [17 7 2 0]

最后一步是按照this blog post中所述删除匿名函数。

在这里,事情变得令人困惑(至少对我来说是这样):rem接受2个参数,而使用数组[17 10 5 1]时我不知道如何应用它们。我尝试了以下电话:
(rem [17 10 5 1]) ; --> gives error
(rem [17 10 5 1] [17 10 5 1]) ; --> also gives error
(rem 17 10) ; --> works, but how do you use it with collections?

有人可以向我解释一下,此rem函数如何与reductions函数一起使用吗?

我不太了解的另一件事是:如何应用这些百分比参数(在#(rem %1 %2)中)?我的意思是它们来自哪里?我尝试通过以下方式调用rem,但出现错误:(#(rem %1 %2) 17 [10 5 1])。为了使这项工作能够完成,reductions函数必须在幕后进行某些操作,对吗?

起初我以为#(rem %1 %2)是一个集合。这些声明与集合类似,可以很容易地被滥用(被刚开始使用Clojure的人使用):
(type #{1 2 3})   ; --> clojure.lang.PersistentHashSet
(type #(1 2 3))   ; --> user$eval12687$fn__12688

有人可以指出我的网站/书/任何可以解释Clojure技巧的的内容,例如“匿名函数的特殊形式”吗?大多数资源只是给出了最简单的结构(类似于所有其他lisp派生类),而没有涉及Clojure的复杂性。我发现a site看起来不错(并且还解释了我上面提到的匿名函数)。 还有其他此类资源吗?

最佳答案

这:

(reductions #(rem %1 %2) amount denominations)

等效于此:
(reductions rem amount denominations)

就像你注意到的
(reductions function start collection)

返回一系列用collection还原function的中间结果的序列(将start作为还原第一步的第一个参数)。 function必须采用两个参数。

因此,结果为:
(reductions function start [1 2 3 4 5])


((function start 1) (function (function start 1) 2) ...)
#(rem %1 %2)语法只是定义匿名函数的简写,该匿名函数接受两个参数(%1%2),在它们上调用rem并返回结果。

等效于:
(fn [a b] (rem a b))

关于clojure - 请向我解释以下Clojure代码,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13990214/

10-13 09:20