(这是一个关于风格的问题.我知道这可以用一堆条件,多方法等来完成)
在以下函数中,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)
我会创建一个"私人"辅助函数:
(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函数.
无关的说明: