Clojure:简洁地转发可选值
Clojure: succinctly forward optional values
我在 Clojure 中编写了一个概率函数,它采用可选的选项散列图:
(defn roll-lte
([n d] (/ n d))
([n d options]
(let [p (/ n d)
roll-type (:type options :normal)]
(cond
(= roll-type :advantage) (- (* p 2) (* p p))
(= roll-type :disadvantage) (* p p)
(= roll-type :normal) p
:else (throw (IllegalArgumentException. "Invalid roll type."))))))
这是按预期工作的,但我们的想法是编写其他函数来构建这个函数——例如:
(defn roll-gte
([n d] (roll-lte (- d n -1) d))
([n d options] (roll-lte (- d n -1) d options)))
roll-lte
中的两个参数使得函数的构建变得笨拙和重复,尤其是在像上面这样 options
只是被转发到 roll-lte
的情况下。有没有更简洁、重复更少的方法来实现?
当我有多个参数的函数时,我通常会尝试让低参数版本调用具有安全默认参数的高参数版本。 "main" 函数的实现通常最终成为最高质量的主体:
(defn roll-lte
([n d] (roll-lte n d nil))
([n d {:keys [type]
:or {type :normal}}]
(let [p (/ n d)]
(case type ;; used case instead of cond here
:advantage (- (* p 2) (* p p))
:disadvantage (* p p)
:normal p
(throw (IllegalArgumentException. "Invalid roll type."))))))
我还在上面的选项映射解构中使用了 :or
来设置 type
的默认值,这允许较低数量的函数只传递一个 nil 选项映射。
(defn roll-gte
([n d] (roll-gte n d nil))
([n d options] (roll-lte (- d n -1) d options)))
(roll-gte 3 4) ;=> 1/2
(roll-gte 3 4 {:type :advantage}) ;=> 3/4
我在 Clojure 中编写了一个概率函数,它采用可选的选项散列图:
(defn roll-lte
([n d] (/ n d))
([n d options]
(let [p (/ n d)
roll-type (:type options :normal)]
(cond
(= roll-type :advantage) (- (* p 2) (* p p))
(= roll-type :disadvantage) (* p p)
(= roll-type :normal) p
:else (throw (IllegalArgumentException. "Invalid roll type."))))))
这是按预期工作的,但我们的想法是编写其他函数来构建这个函数——例如:
(defn roll-gte
([n d] (roll-lte (- d n -1) d))
([n d options] (roll-lte (- d n -1) d options)))
roll-lte
中的两个参数使得函数的构建变得笨拙和重复,尤其是在像上面这样 options
只是被转发到 roll-lte
的情况下。有没有更简洁、重复更少的方法来实现?
当我有多个参数的函数时,我通常会尝试让低参数版本调用具有安全默认参数的高参数版本。 "main" 函数的实现通常最终成为最高质量的主体:
(defn roll-lte
([n d] (roll-lte n d nil))
([n d {:keys [type]
:or {type :normal}}]
(let [p (/ n d)]
(case type ;; used case instead of cond here
:advantage (- (* p 2) (* p p))
:disadvantage (* p p)
:normal p
(throw (IllegalArgumentException. "Invalid roll type."))))))
我还在上面的选项映射解构中使用了 :or
来设置 type
的默认值,这允许较低数量的函数只传递一个 nil 选项映射。
(defn roll-gte
([n d] (roll-gte n d nil))
([n d options] (roll-lte (- d n -1) d options)))
(roll-gte 3 4) ;=> 1/2
(roll-gte 3 4 {:type :advantage}) ;=> 3/4