【问题标题】:How to use let bindings conditionally in Clojure如何在 Clojure 中有条件地使用 let 绑定
【发布时间】:2018-03-10 15:42:06
【问题描述】:

我是 Clojure 的新手,正在尝试简洁地编写一个递归函数来将两个排序的序列合并为一个新的排序序列。

这是我的尝试,无法编译:

(defn seq-merge [a-seq b-seq]
  (cond
    (empty? a-seq) b-seq
    (empty? b-seq) a-seq
    :else (let (if (< (first a-seq) (first b-seq))
                 [f (first a-seq) r (rest a-seq) h b-seq]
                 [f (first b-seq) r (rest b-seq) h a-seq])
            (cons f (seq-merge r h)))))

最初,我想要类似的东西:

(if condition
  (let [...] 
  (let [...]
    (code-that-uses-conditional-bindings))

但似乎每个“让”都需要直接跟在代码后面,所以这不起作用。

如果可以避免的话,目标是不必重复 (cons f (seq-merge r h)) 行两次。

我目前的解决方案是这样的:

(defn seq-merge [a-seq b-seq]
  (cond
    (empty? a-seq) b-seq
    (empty? b-seq) a-seq
    :else (let [a-low? (< (first a-seq) (first b-seq))
                f (if a-low? (first a-seq) (first b-seq))
                r (if a-low? (rest a-seq) (rest b-seq))
                h (if a-low? b-seq a-seq)]
            (cons f (seq-merge r h)))))

但是对于每个绑定值都有一个“if”,这似乎更加笨拙。

【问题讨论】:

标签: if-statement clojure let


【解决方案1】:

您可以尝试使用destructuring。在这种情况下,它并没有什么奇迹,但可以说它更干净一些。

(defn seq-merge [a-seq b-seq]
  (cond
    (empty? a-seq) b-seq
    (empty? b-seq) a-seq
    :else (let [[f r h] (if (< (first a-seq) (first b-seq))
                          [(first a-seq) (rest a-seq) b-seq]
                          [(first b-seq) (rest b-seq) a-seq])]
            (cons f (seq-merge r h)))))

通过非常简单的更改,您也可以使其变得懒惰。这样它就不会溢出堆栈,并且可以处理无限列表。

(defn seq-merge [a-seq b-seq]
  (lazy-seq
   (cond
     (empty? a-seq) b-seq
     (empty? b-seq) a-seq
     :else (let [[f r h] (if (< (first a-seq) (first b-seq))
                           [(first a-seq) (rest a-seq) b-seq]
                           [(first b-seq) (rest b-seq) a-seq])]
             (cons f (seq-merge r h))))))

【讨论】:

    【解决方案2】:

    在函数参数和 let 中使用解构可以稍微清理一下:

    (defn seq-merge [[a & as :as a-seq] [b & bs :as b-seq]]
      (cond
        (empty? a-seq) b-seq
        (empty? b-seq) a-seq
        :else (let [[f r h]
                    (if (< a b) [a as b-seq] [b bs a-seq])]
                (cons f (seq-merge r h)))))
    

    【讨论】:

      猜你喜欢
      • 2014-03-21
      • 2014-06-19
      • 2013-05-31
      • 2015-03-24
      • 2015-11-20
      • 1970-01-01
      • 2020-01-05
      • 1970-01-01
      • 2012-04-11
      相关资源
      最近更新 更多