2015-05-06 25 views
1

我經常發現自己做的事情是這樣的:施加限制Clojure中

(defn f1 [coll] 
    (if (not= (count coll) 2) 
    (throw (IllegalArgumentException. "coll must have length 2."))) 
    (if (odd? (first coll)) 
    (throw (IllegalArgumentException. "first elem must be even."))) 
    (if (even? (second coll)) 
    (throw (IllegalArgumentException. "second elem must be odd."))) 
    (apply * coll)) 

(defn f2 [coll] 
    (if (not= (count coll) 2) 
    (throw (IllegalArgumentException. "coll must have length 2."))) 
    (if (odd? (first coll)) 
    (throw (IllegalArgumentException. "first elem must be even."))) 
    (if (even? (second coll)) 
    (throw (IllegalArgumentException. "second elem must be odd."))) 
    (apply + coll)) 


(defn f3 [coll] 
    (if (not= (count coll) 2) 
    (throw (IllegalArgumentException. "coll must have length 2."))) 
    (if (odd? (first coll)) 
    (throw (IllegalArgumentException. "first elem must be even."))) 
    (if (even? (second coll)) 
    (throw (IllegalArgumentException. "second elem must be odd."))) 
    (apply/coll)) 

在這個簡單的例子,我可以因素的共同部分進行:

(defn qc [coll] 
    (if (not= (count coll) 2) 
    (throw (IllegalArgumentException. "coll must have length 2."))) 
    (if (odd? (first coll)) 
    (throw (IllegalArgumentException. "first elem must be even."))) 
    (if (even? (second coll)) 
    (throw (IllegalArgumentException. "second elem must be odd.")))) 

(defn f1 [coll] 
    (qc coll) 
    (apply + coll)) 

(defn f2 [coll] 
    (qc coll) 
    (apply - coll)) 

(defn f3 [coll] 
    (qc coll) 
    (apply/coll)) 

但在現實世界中的應用這可能很快變得乏味。如果這些功能的qc步驟略有不同,該怎麼辦?如果我想要施加某些類型限制,該怎麼辦?

我想這是動態打字的缺點之一,但也許有辦法讓clojure更容易嗎?

+1

您可能還喜歡:https://github.com/MichaelDrogalis/dire – ClojureMostly

回答

7

函數形式已建成pre and post conditions

user> (defn f1 [coll] 
     {:pre [(= (count coll) 2) 
       (odd? (first coll)) 
       (even? (second coll))]} 
     (apply * coll)) 
#'user/f1 
user> (f1 [1]) 
AssertionError Assert failed: (= (count coll) 2) user/f1 (form-init2783181480380820413.clj:1) 
user> (f1 [2 2]) 
AssertionError Assert failed: (odd? (first coll)) user/f1 (form-init2783181480380820413.clj:1) 
user> (f1 [1 2]) 
2 

這些不打印好的消息,儘管它打印失敗的表現,所以你可以寫清楚,足以傳達出的消息。