是否可以为多签名函数中的所有实现设置公共绑定?

Ped*_*lva 1 clojure

(这是一个关于风格的问题.我知道这可以用一堆条件,多方法等来完成)

在以下函数中,null-vector定义了每个实现.如何为整个功能设置一次?通常,是否可以为所有实现设置公共绑定?

一个闭包不起作用,因为它null-vector需要一个"论证",但我想我能partial做到.但是,仍然需要计算size参数.显然,我想避免重复代码.

(defn path
  "Returns a lazy sequence of vectors representing a monotonic path
   walked over coll in n-dimensional space, where n is the cardinality
   of coll's alphabet."

  ([coll]
     (let [alphabet    (set coll)
           cardinality (count alphabet)
           alpha-map   (apply hash-map (interleave alphabet (range cardinality)))
           null-vector (vec (repeat cardinality 0))]
       (path coll null-vector alpha-map)))

  ([coll alpha-map]
     (let [null-vector (vec (repeat (count (keys alpha-map)) 0))]
       (path coll null-vector alpha-map)))

  ([coll origin alpha-map]
     (let [null-vector (vec (repeat (count origin) 0))
           unit-vector #(assoc null-vector (alpha-map %) 1)
           sum-vectors #(vec (map + %1 %2))]
       (reductions sum-vectors origin (map unit-vector coll)))))
Run Code Online (Sandbox Code Playgroud)

Ale*_*ler 6

我会创建一个"私人"辅助函数:

(defn- null-copy-vector [coll]
  (vec (repeat (count coll) 0)))
Run Code Online (Sandbox Code Playgroud)

然后在函数的每个分支中调用它:

(defn path
  "Returns a lazy sequence of vectors representing a monotonic path
   walked over coll in n-dimensional space, where n is the cardinality
   of coll's alphabet."

  ([coll]
     (let [alphabet    (set coll)
           alpha-map   (zipmap alphabet (iterate inc 0))  ;; note 1
           null-vector (null-copy-vector alphabet)]
       (path coll null-vector alpha-map null-vector)))

  ([coll alpha-map]
     (let [null-vector (null-copy-vector alpha-map)]      ;; note 2
        (path coll null-vector alpha-map null-vector))) 

  ([coll origin alpha-map]
     (path coll origin alpha-map (null-copy-vector origin)))

  ([coll origin alpha-map null-vector]
     (let [unit-vector #(assoc null-vector (alpha-map %) 1)
           sum-vectors #(vec (map + %1 %2))]
       (reductions sum-vectors origin (map unit-vector coll)))))
Run Code Online (Sandbox Code Playgroud)

这可能是因为这是不令人满意的,你null-copy-vector是不是"内部"这里的整体功能,但我认为这是相当地道.在未采取多种arities一个功能,我可能会使用letfn分离出一个"内部"的功能,但不会在这里工作.

像这样打破东西也可以让你a)在其他地方重用基本的构建块函数,b)让你在更小的块中进行测试.您可能希望跳过defn-并且只需使用defn来简化测试(尽管可以通过更多的工作来测试defn- ).

我还打破了一个新的4-arg形式,它将null-vector作为最后一个arg,让你直接传递它,如果你知道它,这样你就可以避免从已经为空的向量重新创建它.如果你想隐藏那个4-arg形式,你可以把它拉成一个单独的defn-helper函数.

无关的说明:

  1. 我使用zipmap和无限序列将您的第一个分支修改为更简单(imho)的impl .
  2. 而不是(count(键映射)),只需执行(计数映射)就足够了(这里的计数在你的辅助函数中).