2016-12-06 71 views
5

我有一個記錄,對於這個規範,我想要生成值但確保當前金額不超過最大金額。 簡化規範會是這樣的:Clojure Spec依賴字段

(s/def ::max-amt (s/and number? #(<= 0 % 1e30))) 
(s/def ::cur-amt (s/and number? #(<= 0 % 1e30))) 
(s/def ::loan (s/cat :max-amt ::max-amt 
        :cur-amt ::cur-amt)) 

我知道我可以在::loan規範有s/and但我想是這樣的:

(s/def :loan (s/cat :max-amt ::max-amt 
        ;; not a real line: 
        :cur-amt (s/and ::cur-amt #(< (:cur-amt %) (:max-amt %))))) 

這是一種約束的規範可用?

注:我知道我可以用0和1之間的數字,表示小數部分但然後我修改數據至角落找尋適應代碼不是其他方式更換CUR-AMT。我不在這裏控制實際應用程序中的數據源。

回答

3

這應該工作(改編自this discussion):

(s/def ::loan (s/and (s/keys :req [::cur-amt ::max-amt]) 
        (fn [{:keys [::cur-amt ::max-amt]}] 
         (< cur-amt max-amt)))) 

(s/conform ::loan {:cur-amt 50 :max-amt 100}) ; => {:cur-amt 50 :max-amt 100} 
(s/conform ::loan {:cur-amt 100 :max-amt 50}) ; => :clojure.spec/invalid 

或者,如果你想堅持到s/cat

(s/def ::loan (s/and (s/cat :cur-amt ::cur-amt 
          :max-amt ::max-amt) 
        (fn [{:keys [cur-amt max-amt]}] 
         (< cur-amt max-amt)))) 

(s/conform ::loan [50 100]) ; => [50 100] 
(s/conform ::loan [100 50]) ; => :clojure.spec/invalid