代码之家  ›  专栏  ›  技术社区  ›  dbyrne

Clojure:cons(seq)与conj(list)

  •  95
  • dbyrne  · 技术社区  · 14 年前

    我知道 cons 返回seq和 conj 返回集合。我也知道 将项目“添加”到集合的最佳末端,并且 欺骗 总是将项目“添加”到前面。这个例子说明了这两点:

    user=> (conj [1 2 3] 4) ; returns a collection
    [1 2 3 4]
    user=> (cons 4 [1 2 3]) ; returns a seq
    (4 1 2 3)
    

    user=> (conj (list 3 2 1) 4) ; returns a list
    (4 3 2 1)
    user=> (cons 4 (list 3 2 1)) ; returns a seq
    (4 3 2 1)
    

    连体 欺骗 表现出不同的行为,还是它们真的可以互换?措辞不同,有没有一个例子,一个列表和一个seq不能等同使用?

    4 回复  |  直到 5 年前
        1
  •  155
  •   Michał Marczyk    14 年前

    一个区别是 conj cons 只需要一个:

    (conj '(1 2 3) 4 5 6)
    ; => (6 5 4 1 2 3)
    
    (cons 4 5 6 '(1 2 3))
    ; => IllegalArgumentException due to wrong arity
    

    另一个区别在于返回值的类别:

    (class (conj '(1 2 3) 4))
    ; => clojure.lang.PersistentList
    
    (class (cons 4 '(1 2 3))
    ; => clojure.lang.Cons
    

    请注意,这些并不是真正可互换的;特别地, clojure.lang.Cons 不执行 clojure.lang.Counted ,所以 count (next (cons 4 '(1 2 3)) 成为一个 PersistentList 因此 Counted

    我相信,这些名字背后的意图是 施工方法(施工顺序) 1 seq 正在建造 欺骗 next rest 部分由于应用 序号 第二个论点;如上图所示,整件事都是一流的 clojure.lang.Cons公司 . 相反, 总是返回与传递给它的集合类型大致相同的集合(大概是因为 PersistentArrayMap PersistentHashMap 一旦超过9个条目。)


    传统上,在Lisp世界, 欺骗 函数构造一个没有传统 cdr . 一般用法 欺骗 意思是“构造某种类型的记录或其他类型的记录以将多个值保存在一起”目前在编程语言及其实现的研究中是普遍存在的;这就是“避免考虑”的意思。

        2
  •  12
  •   Daniel Yankowsky    14 年前

    您可以将conj看作是一个“insert-somewhere”操作,cons看作是一个“insert-at-the-head”操作。在列表中,最合乎逻辑的是在开头插入,因此conj和cons在本例中是等价的。

        3
  •  9
  •   user323818    14 年前

    conj alter 更新文件时 ref 以某种顺序:

    (dosync (alter a-sequence-ref conj an-item))
    

    (conj a-sequence-ref an-item) 以线程安全的方式。这对我没用 cons . 请参阅中有关并发的章节 Programming Clojure

        4
  •  3
  •   FredAKA    11 年前

    另一个区别是列表的行为?

    (list? (conj () 1)) ;=> true
    (list? (cons 1 ())) ; => false
    
        5
  •  -1
  •   Alan Thompson    5 年前

    dedicated functions in the Tupelo Library

    (append [1 2] 3  )   ;=> [1 2 3  ]
    (append [1 2] 3 4)   ;=> [1 2 3 4]
    
    (prepend   3 [2 1])  ;=> [  3 2 1]
    (prepend 4 3 [2 1])  ;=> [4 3 2 1]