Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 通过表达式的条件线程_Clojure - Fatal编程技术网

Clojure 通过表达式的条件线程

Clojure 通过表达式的条件线程,clojure,Clojure,我试着做下面的事情 val = initValue; if (test1(val)) { val = fn1(val); } if (test2(val)) { val = fn2(val); } return val; 我在clojure core中找到的唯一方法是使用cond->。我希望我能做到这一点 (cond-> initValue test1 fn1 test2 fn2) 但是,cond->中的条件不是函数。它似乎不允许我将fn1的结果传递给test2 这样做的惯

我试着做下面的事情

val = initValue;
if (test1(val)) { val = fn1(val); }
if (test2(val)) { val = fn2(val); }
return val;
我在clojure core中找到的唯一方法是使用
cond->
。我希望我能做到这一点

(cond-> initValue
   test1 fn1
   test2 fn2)
但是,
cond->
中的条件不是函数。它似乎不允许我将
fn1
的结果传递给
test2


这样做的惯用方法是什么?

好的。函数结果和谓词之间存在数据依赖关系,因此我仅使用clojure.core提出的“最好的”方法是将
as->
cond->

(as-> initValue data
      (cond-> data (test1 data) (f1 data))
      (cond-> data (test2 data) (f2 data)))
另一种方法是我自己的助手

(defn ->when-update
  "Function of a value, a predicate, an updater and optional
  varargs. If the predicate is true of the value, returns (apply f x
  args), otherwise returns x.

  Example:
    (-> 1 (->when-update #(<= 0 %) inc))"
  [x pred f & args]
  (if (pred x)
    (apply f x args)
    x))
这样行吗

(defmacro cond-chain [init & stuff]
  (let [pairs (partition 2 stuff)
        step-form (fn [[test func]]
                    `((fn [x#] (if (~test x#) (~func x#) x#))))]
    (list* '->> init (map step-form pairs))))
比如说,

(cond-chain 7, even? inc, odd? #(* 2 %))
;14

(cond-chain 7, odd? inc, odd? #(* 2 %))
;8

(cond-chain 7, zero? inc, even? #(* 2 %))
;7
如您所见,它构造了一个表单,有条件地应用一系列函数中的每一个


或者,在不使用宏的情况下:

(defn cond-chain [init & stuff]
  (let [pairs (partition 2 stuff)]
    (reduce (fn [acc [test func]] (if (test acc) (func acc) acc)) init pairs)))
(defn cond-chain [init & stuff]
  (let [pairs (partition 2 stuff)]
    (reduce (fn [acc [test func]] (if (test acc) (func acc) acc)) init pairs)))