我有这个Clojure代码:
(defn apply-all-to-arg [& s]
(let [arg (first s)
exprs (rest s)]
(for [condition exprs] (condition arg))))
(defn true-to-all? [& s]
(every? true? (apply-all-to-arg s)))
这是测试代码:
(apply-all-to-arg 2 integer? odd? even?)
=> (true false true)
(every? true? (apply-all-to-arg 2 integer? odd? even?)
=>假
(true-to-all? 2 integer? odd? even?)
=>真
我的问题是: 为什么功能真实?返回true(它必须返回false)
答案 0 :(得分:3)
true-to-all?
使用单个参数apply-all-to-arg
调用s
。所以你不是在呼叫(every? true? (apply-all-to-arg 2 integer? odd? even?)
,而是在呼叫:
(every? true? (apply-all-to-arg (list 2 integer? odd? even?))
因此,在apply-all-to-arg
中,arg
的值将为该列表,exprs
的值将为空列表。因为无论条件是什么,every?
对于空列表都是正确的,所以你会得到回报。
要解决此问题,您可以更改apply-all-to-arg
,以便它接受列表而不是可变数量的参数,或者您可以更改true-to-all?
,以便它传递{{1}的内容作为多个参数而不是单个列表(通过使用s
)。
答案 1 :(得分:2)
创建一个将多个函数并行应用于一个参数的函数的默认Clojure函数是juxt:
=> ((juxt integer? odd? even?) 2)
[true false true]
=> (every? true? ((juxt integer? odd? even?) 2))
false
=> (defn true-to-all? [a & fns]
(every? true? ((apply juxt fns) a)))
=> (true-to-all? 2 integer? odd? even?)
false
如果与juxt结合使用的函数都采用多个参数,那么它也能正常工作
=> ((juxt + - / *) 6 3)
[9 3 2 18]
答案 2 :(得分:0)
因为当您致电true-to-all?
时,参数s
就是一个列表,因此您实际上正在调用(apply-all-to-arg '(2 integer? odd? even?))
尝试像这样定义true-to-all?
:
(defn true-to-all? [& s]
(every? true? (apply apply-all-to-arg s))
答案 3 :(得分:0)
您还可以像下面一样定义您的功能,以使其更清晰。
(defn apply-all-to-arg [v & fns]
(map #(% v) fns))
因为这使得函数定义清楚,它需要一个值和可选函数来应用于该值。