我对Clojure比较陌生,并且一直在通过4Clojure工作。我正在研究问题31,打包序列,http://www.4clojure.com/problem/31#prob-title。目标是将连续的重复项打包到子列表中。我知道可以使用&&
来实现,但是我想尝试使用(partition-by ...)
完全写出来。我的尝试如下:
(loop ... (recur ...))
该程序似乎陷入了无限循环,因此我通过IDE的调试器运行了该程序。看来,当(defn my-subpack
[paramSeq]
;Track the output sequence
;Track the current sub sequence
;Track the next input value to consider
(loop [outSeq []
currSub (vector (first paramSeq))
inSeq (rest paramSeq)]
;If the inSeq is empty then we return outSeq
(println (empty? inSeq))
(if (empty? inSeq)
outSeq)
;If the next value from inSeq is in the currSub then we add it to it
(if (= (first currSub) (first inSeq))
(recur outSeq (conj currSub (first inSeq)) (rest inSeq))
(recur (conj outSeq currSub) (vector (first inSeq)) (rest inSeq)))
))
为空时,返回inSeq
的{{1}}语句不会运行。就像if
返回outSeq
一样被跳过。在下面,我包括了无限循环开始时的IDE屏幕快照。请注意,(empty? inSeq)
在表达式求值器中返回0,但调试器将其显示为计数为1。这是无限循环开始时的IDE。计数在表达式求值器中显示为0,但在调试器中也显示为1。
在我看来,我已经进行了一些重大的疏忽,但我还没有足够的经验来了解它!
答案 0 :(得分:1)
问题在于,当inSeq
为空时,机器什么也不做,而是继续执行下一条语句(在两种情况下都执行recur
)。如果outSeq
为空,则可能需要返回inSeq
作为循环表达式的结果:
(if (empty? inSeq)
outSeq
;; If the next value from inSeq is in the currSub then we add it to it
(if (= (first currSub) (first inSeq))
(recur outSeq (conj currSub (first inSeq)) (rest inSeq))
(recur (conj outSeq currSub) (vector (first inSeq)) (rest inSeq))))