对clojure中的函数args施加限制

时间:2015-05-06 22:01:22

标签: 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 个答案:

答案 0 :(得分: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

这些不打印好消息,虽然它打印失败的表达式,因此您可以清楚地写出来以便传达消息。