(clojure.core / seq)而不是列表

时间:2017-03-15 18:00:21

标签: clojure

我不明白为什么而不是正常的列表我回忆(clojure.core / seq)。 我的代码

(defn del-list [arg-list lvl] (do
                                (cond
                                 (= lvl 1) (remove seq? arg-list)
                                 :else (map #(if (seq? %)
                                               (del-list % (- lvl 1))
                                               %
                                               ) arg-list)
                                )
                            ))
(println (del-list `(1 2 3 `(1 2 `(1 2 3) 3) 1 2 3) 2))
;result=> (1 2 3 (clojure.core/seq) 1 2 3)

为什么会这样?我不知道如何有效搜索这个,谷歌的所有链接都指向我,有关seqseq?的文档。

1 个答案:

答案 0 :(得分:1)

像@ClojureMostly在评论中所说,不要使用bacticks,使用单引号。也不要嵌套它们,一个就足够了。

所以,像这样调用你的函数:

(println (del-list '(1 2 3 (1 2 (1 2 3) 3) 1 2 3) 2))

将解决您当前的问题。

进一步深入,单引号(仅称为引用)和反引号(称为语法引用)之间存在一些差异。

在引用某些内容时,您说您只需要数据结构,不应将其评估为代码。在clojure中,代码是数据,因此(+ 1 2)是一个带有符号和两个数字的列表,当作为代码进行评估时,它会变为3.因此,(+ 1 2) => 3'(+ 1 2) => (+ 1 2)

语法引用类似,但它查找事物的命名空间,你可以在内部取消引用。这使它对编写宏很有用。

;; Looks up the namespaces of symbols to avoid the problem of variable capture
`(+ 1 2) ;=> (clojure.core/+ 1 2)

;; You can unquote parts of the expression.
;; ~ is unquote ~@ is unqoute splicing
;; That should give you the vocabulary to google this.
`(+ 1 2 3 ~(* 2 2)) ;=> (clojure.core/+ 1 2 3 4)

嵌套引号绝不是你想要的。 (除非你交替引用和取消引用,即便如此,它通常会令人困惑)

在clojure中,您通常将顺序事物表示为向量[1 2 3](O(n)随机访问,最后增长),除非您特别想要数据链表的某些属性。 (就像表示堆栈一样,列表可以有效地添加和删除第一个元素。)

(defn del-list [arg-list lvl]
  ;; You don't need the do, there's an implicit do in many special forms
  ;; like let, fn and defn
  ;; Also you only had one thing in your do, in that case it doesn't do anything

  ;; There's only one condition, so I'd use if instead of cond
  (if (= lvl 1)

    ;; And, like someone mentioned in the comments,
    ;; what you probably want is sequential? instead of seq?
    (remove sequential? arg-list)
    (map #(if (sequential? %)
            (del-list % (dec lvl)) ; dec stands for decrement
            %)
         arg-list)))


;; This works
(println (del-list '(1 2 3 (1 2 (1 2 3) 3) 1 2 3) 2))

;; But this is more idiomatic (modulo specific reasons to prefer lists)
(println (del-list [1 2 3 [1 2 [1 2 3] 3] 1 2 3] 2))

;; If you change map to mapv, and wrap remove with vec it will return vectors
(defn del-vec [arg-vec lvl]
  (if (= lvl 1)
    (vec (remove sequential? arg-vec))
    (mapv #(if (sequential? %)
             (del-vec % (dec lvl)) ; dec stands for decrement
             %)
          arg-vec)))

(println (del-vec [1 2 3 [1 2 [1 2 3] 3] 1 2 3] 2))

;; But most of the time you don't care about the specific type of sequential things

至于你的实际问题,为什么会出现clojure.core / seq,我不知道。这不是你如何使用引用,所以它从来没有出现过。