回顾我的初学者clojure反转函数
我刚刚开始我的clojure之旅,我想知道是否有人能指出我下面函数中的初学者错误,这只是颠倒了列表。我知道已经有了一个反向函数,所以这纯粹是为了学习回顾我的初学者clojure反转函数,clojure,Clojure,我刚刚开始我的clojure之旅,我想知道是否有人能指出我下面函数中的初学者错误,这只是颠倒了列表。我知道已经有了一个反向函数,所以这纯粹是为了学习 (defn rev ([l] (if (= (count l) 1) l (rev '() l))) ([l orig] (if (= (count orig) 0) l (rev (conj l (first orig)) (rest orig))))) 在我的辩护中,它确实有效,但我发现自己在cloju
(defn rev
([l]
(if (= (count l) 1) l (rev '() l)))
([l orig]
(if (= (count orig) 0)
l
(rev (conj l (first orig)) (rest orig)))))
在我的辩护中,它确实有效,但我发现自己在clojure中经常做的事情是重载参数列表,以便在我需要一个工作列表时加以考虑,如本例中我将新项连接到的工作列表。如果您不想用其他算术公开函数,请在本地定义并使用它们:
(defn rev [l]
((fn rev2 [l orig]
(if (empty? orig)
l
(rev2 (conj (first orig) l) (rest orig))))
() l))
您可能会发现使用let或letfn更容易:
顺便说一下
如果你只是想知道是否有,不要计算序列
里面有什么。使用seq或empty?。
去掉1元素序列的特例:它不是特例。
不需要引用。
当然,我们可以也应该使用recur而不是rev2的递归调用,以避免在长序列上破坏堆栈:
(defn rev [l]
(letfn [(rev2 [l orig]
(if (empty? orig)
l
(recur (conj l (first orig)) (rest orig))))]
(rev2 () l)))
首先,首先查看现有的函数实现是一个非常好的主意:
(defn reverse [coll]
(reduce conj () coll))
与代码的主要区别在于,现有的reverse实现使用高阶函数。尽可能使用高阶函数而不是递归是一种很好的做法
-
但是让我们假设您的目标是学习递归。下面是我应该如何写的:
(defn rev
([coll]
(rev coll ()))
([coll acc]
(if-let [[h & ts] (seq coll)]
(recur ts (conj acc h))
acc)))
让我们仔细看看我的代码
首先,我使用and检查coll是否为非空集合
然后我用它来获取给定集合的第一个元素和它的其余部分
换句话说,我的建筑
(if-let [[h & ts] (seq coll)]
(recur ts (conj acc h))
acc)
可以重写为if、let、first和rest:
这几乎就是你自己写的
最后一件重要的事情是,我正在使用,而不是直接调用rev。
它允许clojure编译器执行尾部递归优化
您还应该考虑使用,而不是创建重载函数,除非您想公开两个参数:
(defn rev [coll]
(loop [coll coll
acc ()]
(if-let [[h & ts] (seq coll)]
(recur ts (conj acc h))
acc)))
-
因此,代码中有很多地方需要改进。但我只能看到三个真正的错误:
你应该使用recur;
检查没有意义=计数l 1;
您应该使用而不是=count orig 0。
在这里,我修复了代码中的两个错误:
(defn rev
([l]
(rev '() l))
([l orig]
(if (empty? orig)
l
(recur (conj l (first orig)) (rest orig)))))
这个问题似乎离题了,因为它是关于代码审查的-那么为什么会有代码审查标签?@dagda1发布关于代码审查工具的问题?@dagda1我真的相信顺便说一句,你可以在@dagda1上提出关于这个的讨论。自从你发表评论后,我做了一些编辑。请检查我答案的最终版本。
(defn rev [coll]
(loop [coll coll
acc ()]
(if-let [[h & ts] (seq coll)]
(recur ts (conj acc h))
acc)))
(defn rev
([l]
(rev '() l))
([l orig]
(if (empty? orig)
l
(recur (conj l (first orig)) (rest orig)))))