将函数组合为 clojure 中高级函数的可选参数
composing functions as optional arguments to higher-level function in clojure
我正在尝试在 Clojure 中创建一个多参数函数,如果给定一个向量参数,只需将另一个函数应用于该向量;如果给定一个向量加上 1 个或多个函数,则将这些函数的组合映射到向量上,然后应用第三个函数。但不知何故,我似乎无法访问第一个之外的任何可选参数。
玩具示例代码:
(defn times2 [num] (* 2 num))
(defn square [num] (* num num))
(defn plusfiveall [vec-of-nums] (map #(+ 5 %) vec-of-nums))
(defn toynums
([vec-of-nums]
(plusfiveall vec-of-nums))
([vec-of-nums & [funcs]]
(let [moremath (comp funcs)]
(plusfiveall (map moremath vec-of-nums)))))
我认为应该发生的事情:
(toynums [1 2 3])
= (6 7 8)
(toynums [1 2 3] times2)
= (7 9 11)
(toynums [1 2 3] times2 square)
= (7 13 23)
但是虽然前两个示例按预期工作,但第三个示例无法应用 square
:相反,我得到 (toynums [1 2 3] times2 square)
--> (7 9 11)
为了深入研究这个问题,我也尝试了一个没有映射的版本,并且有同样令人惊讶的行为:
(defn comp-nomap
([num] (plusfive num))
([num & [funcs]]
(let [funmath (comp funcs)]
(plusfive (funmath num)))))
(comp-nomap 3)
= 8 符合预期
(comp-nomap 3 times2)
= 11 符合预期
但 (comp-nomap 3 times2 square)
也 = 11,而不是应有的 23。
求助?谢谢!
这个结构产生了预期的答案:
(defn toynums
([vec-of-nums]
(plusfiveall vec-of-nums))
([vec-of-nums & funcs]
(let [moremath (apply comp funcs)]
(plusfiveall (map moremath vec-of-nums)))))
&
之后的参数会自动收集到一个序列中,这样里面就可以使用apply
,这样就可以让comp
函数拥有序列的内容作为参数传递给它。所以你真的做对了,只是错过了一件事。您需要查找 'varadic' 个参数。
你的第二个参数使用可变参数的解构,它总是从提供的参数中提取第一个函数。您还需要 apply
comp
对序列中的参数起作用:
(defn comp-nomap
([num] (plusfive num))
([num & funcs]
(let [funmath (apply comp funcs)]
(plusfive (funmath num)))))
我正在尝试在 Clojure 中创建一个多参数函数,如果给定一个向量参数,只需将另一个函数应用于该向量;如果给定一个向量加上 1 个或多个函数,则将这些函数的组合映射到向量上,然后应用第三个函数。但不知何故,我似乎无法访问第一个之外的任何可选参数。
玩具示例代码:
(defn times2 [num] (* 2 num))
(defn square [num] (* num num))
(defn plusfiveall [vec-of-nums] (map #(+ 5 %) vec-of-nums))
(defn toynums
([vec-of-nums]
(plusfiveall vec-of-nums))
([vec-of-nums & [funcs]]
(let [moremath (comp funcs)]
(plusfiveall (map moremath vec-of-nums)))))
我认为应该发生的事情:
(toynums [1 2 3])
= (6 7 8)
(toynums [1 2 3] times2)
= (7 9 11)
(toynums [1 2 3] times2 square)
= (7 13 23)
但是虽然前两个示例按预期工作,但第三个示例无法应用 square
:相反,我得到 (toynums [1 2 3] times2 square)
--> (7 9 11)
为了深入研究这个问题,我也尝试了一个没有映射的版本,并且有同样令人惊讶的行为:
(defn comp-nomap
([num] (plusfive num))
([num & [funcs]]
(let [funmath (comp funcs)]
(plusfive (funmath num)))))
(comp-nomap 3)
= 8 符合预期
(comp-nomap 3 times2)
= 11 符合预期
但 (comp-nomap 3 times2 square)
也 = 11,而不是应有的 23。
求助?谢谢!
这个结构产生了预期的答案:
(defn toynums
([vec-of-nums]
(plusfiveall vec-of-nums))
([vec-of-nums & funcs]
(let [moremath (apply comp funcs)]
(plusfiveall (map moremath vec-of-nums)))))
&
之后的参数会自动收集到一个序列中,这样里面就可以使用apply
,这样就可以让comp
函数拥有序列的内容作为参数传递给它。所以你真的做对了,只是错过了一件事。您需要查找 'varadic' 个参数。
你的第二个参数使用可变参数的解构,它总是从提供的参数中提取第一个函数。您还需要 apply
comp
对序列中的参数起作用:
(defn comp-nomap
([num] (plusfive num))
([num & funcs]
(let [funmath (apply comp funcs)]
(plusfive (funmath num)))))