2017-06-10 83 views
2

我有下面的代碼:如何在cond的測試和結果中使用結果?

(cond 
    (case-1? (compute-1 x)) (compute-1 x) 
    (case-2? (compute-2 x)) (compute-2 x) 
    (case-3? (compute-3 x)) (compute-3 x)) 

我想避免的compute-1compute-2compute-3重複計算。一種選擇是:

(let [result-1 (compute-1 x) 
     result-2 (compute-2 x) 
     result-3 (compute-3 x)] 
    (cond 
    (case-1? result-1) result-1 
    (case-2? result-2) result-2 
    (case-3? result-3) result-3)) 

現在,我不重複計算,但如果現在(case-1? result-1)而不是計算結果爲真,result-2result-3計算了沒有理由。
行爲上我想是這樣的:

(let [result-1 (compute-1 x)] 
    (if (case-1? result-1) 
    result-1 
    (let [result-2 (compute-2 x)] 
     (if (case-2? result-2) 
     result-2 
     (let [result-3 (compute-3 x)] 
      (if (case-3? result-3) 
      result-3)))))) 

但是這個代碼顯然是迅速成爲難以管理。有沒有更好的解決這個問題?

+0

如果你不想要宏或外部dep,你可以使用'delay'來避免計算。 – ClojureMostly

回答

3

有一個名爲better cond的庫,它正好解決了這個問題。

它這樣使用:

(ns foo.core 
    (:require 
    [better-cond.core :as b])) 

(b/cond 
    :let [result-1 (compute-1 x)] 
    (case-1? result-1) result-1 

    :let [result-2 (compute-2 x)] 
    (case-2? result-2) result-2 

    :let [result-3 (compute-3 x)] 
    (case-3? result-3) result-3) 

這片段將macroexpand編寫一個類似您的最後一個例子。