2011-09-15 2 views
10

のClojure:Clojureのシーケンスと一致しませんか?

1:13 user=> (first (conj '(1 2 3) 4)) 
4 
1:14 user=> (first (conj [1 2 3] 4)) 
1 
; . . . 
1:17 user=> (first (conj (seq [1 2 3]) 4)) 
4 

私は何が起こっているかを理解しますが、この作品は違っ必要がありますか?

+0

私は今年5月からClojureを学んでいます。 Clojureの前にLispのような言語を学んだことがなかったので、このようなエクササイズを非常に参考にしていることがわかりました。 – octopusgrabbus

答えて

20

ドキュメント:

CONJ [OIN]。 xs が追加された新しいコレクションを返します。 (conjnil item)は(item)を返します。 「追加」は具体的なタイプによって異なる「場所」で が発生することがあります。

ベクトルの最後に要素を追加する方が効率的ですが、リストの先頭で要素を追加する方が効率的です。 conjは、それを与えるデータ構造にとって最も効率的なものを使用します。

あなたが与える例で

'(1 2 3)(seq [1 2 3])両方[1 2 3]はしませんが、(documentation for seq?を参照)ISeqを実装しています。

Clojureのconjは、基本的なデータ構造上でconsメソッド(cons関数と混同しないでください - このメソッドは内部クロージャコードです)を呼び出します。ベクトルの場合(PersistentVector)、consは最後に要素を追加しますが、リストは先頭に追加されます(PersistentListの場合はconsメソッドは新しい要素を先頭に、既存のリストを末尾に持つ新しいリストを返します) 。

+0

私が思う最後のパラグラフは間違っています(少なくともClojure 1.2.1では): '(cons 4 [1 2 3])'は、例えば、要素を追加するのではなく、その前に付加して '(4 1 2 3 ) '。しかし、答えの残りは絶対に正しいです。 –

+0

Zachですが、Clojureの 'cons'関数(' Clojure.lang.RT/cons'で実装されています)は 'PersistentVector'や' PersistentList'などで実装されている 'cons'メソッドとは異なります。 – Gert

+0

ああ、今私はあなたを理解しています。それが表現されている方法では、あなたがコア関数 "cons"を参照しているように思えます。 –

6

あなたはClojure Data Structures

を見ればあなたはCONJは、リストやベクトルと異なる動作をすることを確認できます。

conjは、追加された項目をリストの前とベクトルの最後に置きます。

は、私はまた、いくつかの素晴らしい例がありClojure API conj

を見てお勧めします。 ClojureDocs全体には、Clojureのほとんどのコマンドには非常に良い例がいくつかあります。 (clojure.orgから)conjため

関連する問題