使用以下代码,尽管所有重复都在尾部位置,但我得到#<CompilerException java.lang.UnsupportedOperationException: Can only recur from tail position (NO_SOURCE_FILE:4)>
。如果我从单参数版本中删除recur,它就会停止抱怨。为什么会这样?
(defn remove-duplicates "Removes duplicate elements of lst.
For example, given (1 2 3 1 4 1 2), remove-duplicates returns a sequence
containing the elements (1 2 3 4), in some order."
[lst] (recur (rest lst) (set (first lst)))
[lst uniques] (cond (zero? (count lst)) uniques
:else (cond
(some (partial = (first lst)) uniques)
(recur (rest lst) uniques)
:else
(recur (rest lst) (first lst)))))
答案 0 :(得分:4)
你没有正确地分割多个机构。应该阅读(defn foo ([x] (...)) ([x y] (...)))
。这会导致编译器认为你做的事情完全不同,这可能是你的问题所在。
答案 1 :(得分:1)
首先:你知道你想要的只是(def remove-duplicates set)
或 - 如果你想要一个矢量 - (def remove-duplicates-vec (comp vec set))
,对吗?
这里有五件事:
(set (first lst))
,因为set
想要竞争。如果你愿意,可以做(set (vector (first [1 2 3 2 3])))
之类的事情,但这既不美观也不惯用(cond pred1 code1 :else (cond pred2a code2a :else code2b))
:(cond pred1 code1 pred2a code2a :else code2b)
- 您所做的就是cond
macro,就好像它是if
一样(内置到目前为止)我知道)[1 2 3 2 1]
开始
([2 3 2 1] #{1})
(我已经跳过了无聊的部分)([3 2 1] 2)
,这显然是错误的,因为你想要([3 2 1] #{1 2})
。您可能想要致电(recur (rest lst) (conj uniques (first lst)))
总结:
(defn remove-duplicates
([lst] (remove-duplicates (rest lst) #{(first coll)}))
([lst uniques]
(cond
(zero? (count lst)) uniques
(some (partial = (first lst)) uniques)
(recur (rest lst) uniques)
:else
(recur (rest lst) (conj uniques (first lst))))))