Recursion 陷入clojure的递归-缺少括号

Recursion 陷入clojure的递归-缺少括号,recursion,clojure,Recursion,Clojure,我正在编写clojure递归函数,以便: (luty [1 2 3 4]) 应该有如下输出: ((1 2 3 4) (2 3 4) (3 4) (4) () 我的代码是: (defn luty [a1] (if (empty? a1) (list ) (cons (seq a1) (luty (rest a1) ) ))) 我得到了输出: ((1 2 3 4) (2 3 4) (3 4) (4)) //comment missing a () 有人能告诉我哪里出错

我正在编写clojure递归函数,以便:

(luty [1 2 3 4])
应该有如下输出:

((1 2 3 4) (2 3 4) (3 4) (4) ()
我的代码是:

(defn luty [a1]
 (if (empty? a1)
   (list )
     (cons (seq a1)  (luty (rest a1) )
  )))
我得到了输出:

((1 2 3 4) (2 3 4) (3 4) (4)) //comment missing a ()

有人能告诉我哪里出错了吗?

如果我们打印出流程并查看倒数第二个操作:

user> (defn luty [a1]
        (println "a1 is" a1)
         (if (empty? a1)
             ()
           (cons (seq a1) (luty (rest a1)))))
#'user/luty
user> (luty [1 2 3 4])
a1 is [1 2 3 4]
a1 is (2 3 4)
a1 is (3 4)
a1 is (4)
a1 is ()
((1 2 3 4) (2 3 4) (3 4) (4))
user> (cons '(4) ())
((4))
我们可以看到,将
(4)
添加到空列表的结果是
((4))
,而不是您最可能想要的
((4)()
。这可以通过将基本情况设置为包含空列表的列表来解决,而不仅仅是一个空列表

user> (defn luty [a1]
         (if (empty? a1)
           '(())
           (cons (seq a1) (luty (rest a1)))))
#'user/luty
user> (luty [1 2 3 4])
((1 2 3 4) (2 3 4) (3 4) (4) ())

如果我们打印流程并查看倒数第二个操作:

user> (defn luty [a1]
        (println "a1 is" a1)
         (if (empty? a1)
             ()
           (cons (seq a1) (luty (rest a1)))))
#'user/luty
user> (luty [1 2 3 4])
a1 is [1 2 3 4]
a1 is (2 3 4)
a1 is (3 4)
a1 is (4)
a1 is ()
((1 2 3 4) (2 3 4) (3 4) (4))
user> (cons '(4) ())
((4))
我们可以看到,将
(4)
添加到空列表的结果是
((4))
,而不是您最可能想要的
((4)()
。这可以通过将基本情况设置为包含空列表的列表来解决,而不仅仅是一个空列表

user> (defn luty [a1]
         (if (empty? a1)
           '(())
           (cons (seq a1) (luty (rest a1)))))
#'user/luty
user> (luty [1 2 3 4])
((1 2 3 4) (2 3 4) (3 4) (4) ())

cons的返回值是一个列表,第一个元素是第一个参数,列表的其余部分是第二个参数。如果第二个参数为空或nil,则意味着您将获得一个列表,其中第一个参数为单个成员

这是因为列表是(至少在clojure中是概念上的)带有两个空格单元的链表;一个指针指向head元素,一个指针指向tail(另一个列表,在clojure中保证是一个类似seq的东西-在许多其他Lisp中,您可以将第二个指针设置为您想要的任何值,因此不能保证从cons中获得“正确的”列表)。“尾部”位置的零表示列表结束


列表是最容易实现和理解的持久(从绝对意义上说是不可变的、结构共享的)数据结构。

cons的返回值是一个列表,第一个元素是第一个参数,列表的其余部分是第二个参数。如果第二个参数为空或nil,则意味着您将获得一个列表,其中第一个参数为单个成员

这是因为列表是(至少在clojure中是概念上的)带有两个空格单元的链表;一个指针指向head元素,一个指针指向tail(另一个列表,在clojure中保证是一个类似seq的东西-在许多其他Lisp中,您可以将第二个指针设置为您想要的任何值,因此不能保证从cons中获得“正确的”列表)。“尾部”位置的零表示列表结束


列表是最容易实现和理解的持久(从绝对意义上说是不可变的、结构共享的)数据结构。

只是让您以不同的方式来看待它:

user> (defn luty [a1]
        (reductions (fn [c _] (rest c)) (or (seq a1) '()) (-> a1 count range)))
   => #'user/luty
user> (luty [1 2 3 4])
   => ((1 2 3 4) (2 3 4) (3 4) (4) ())
user> (luty [])
   => (())
user> (luty nil)
   => (())

只是给你一个不同的视角:

user> (defn luty [a1]
        (reductions (fn [c _] (rest c)) (or (seq a1) '()) (-> a1 count range)))
   => #'user/luty
user> (luty [1 2 3 4])
   => ((1 2 3 4) (2 3 4) (3 4) (4) ())
user> (luty [])
   => (())
user> (luty nil)
   => (())