2011-11-14 45 views
5

對不起,如果這個問題沒有任何意義。程序流程 - 如果一個計算失敗,則退出操作

我目前正在編寫一個小應用程序,我想'鏈接'一起形成更廣泛的計算功能。

因此,例如,我有一個函數調用Web服務,並返回hash-map作爲結果,或nil如果是錯誤或出錯了。鏈中的下一個函數接受地圖並進行一些進一步處理,然後將其傳遞給下一個函數......等等。

事情是,如果第一個函數失敗,它會通過nil到下一個函數,並會拋出一個空指針(或其他),我不希望它甚至到達這個階段。 換句話說,如果鏈條中的一個項目失敗,我希望整個計算失敗。

例如

;successful computation = function1 returns W -> function2 returns X -> function3 returns Y -> function4 returns Z -> Z 
;failed computation = function1 returns W -> function2 returns X -> function3 returns nil -> nil 
(-> (function1 "http://webservice.com") (function2) (function3) (function4)) 

的事情是我不想被在開始與if(nil? arg)亂扔我的每一個功能,最好我想,可能照顧,對我的抽象,但我真的不避讓了什麼Clojure中

我想採用Scala的風格Option類型可以是Some(value)None,但我仍然需要垃圾我的這些檢查代碼在開始的

任何意見或的可用回覆將非常感謝

回答

4

Clojure Contribalgo.monad包含一個Scala調用的monad的實現Option。它被稱爲maybe-m,並通過將nil作爲None進行工作。你可以這樣使用它:

(ns mulk.monads-test 
    (:refer-clojure) 
    (:use clojure.repl 
     clojure.algo.monads)) 

(defn function1 [x] 
    x) 

(defn function2 [x] 
    (+ x 10)) 

(defn function3 [x] 
    (* x 2)) 

(defn calc-stuff [thing] 
    (domonad maybe-m 
    [x1 (function1 thing) 
    x2 (function2 x1) 
    x3 (function3 (+ x2 10))] 
    x3)) 

(calc-stuff 10) ;=> 60 
(calc-stuff nil) ;=> nil 
+0

真棒這個是我在找的東西,看起來這個庫裏有更多的抽象,這對我來說也是非常有用的! – djhworld

4

clojure.contrib.core有-?>宏,它完全符合你的要求。

http://clojuredocs.org/clojure_contrib/clojure.contrib.core/-_q%3E

+0

啊哈!好東西。我不知道' - ?>'宏是否僅僅是Matthias回答中描述的'maybe-m' monad的包裝? – djhworld

+0

不,實現是獨立的:https://github.com/clojure/clojure-contrib/blob/master/modules/core/src/main/clojure/clojure/contrib/core.clj –

1

你可以定義一個輔助函數用於鏈接的函數調用,並在兩者之間檢查零值:

(defn chain [v & functions] 
    (cond (nil? v) nil 
     (empty? functions) v 
     :else (recur ((first functions) v) (rest functions)))) 

然後調用它像這樣:

(chain "http://webservice.com" function1 function2 function3 function4) 
相關問題