7

clojure には、vector と list に対して異なる動作をする関数がいくつかあります。2 つの質問があります。

1) それは何のために良いですか? Clojure の作成者にはこれを行う十分な理由があると思いますが、私にはわかりません。

2)データがリストまたはベクトルにある場合でも同じように動作するこれらの関数のタイプセーフバリアントをどのように作成できますか?

定義されている関数 conj は、次の動作をします。

(conj [1 2 3] 4)
[1 2 3 4]

(conj '(1 2 3) 4)
(4 1 2 3)

次の動作を持つ関数 my-conj が必要です

(my-conj [1 2 3] 4)
[1 2 3 4]

(my-conj '(1 2 3) 4)
(1 2 3 4)

同じ動作をする他の関数 (cons、into、peek、pop) があるので、この構造がそれらすべてに簡単に適応できるとよいでしょう。

4

2 に答える 2

9

データ構造の実装方法により、データ構造の動作をわずかに変える方が効率的です。たとえば、リストの先頭にアイテムを追加するのは簡単ですが (概念的には既存のリストの先頭にアイテムをリンクするだけです)、ベクトルの先頭にアイテムを追加するのは困難です (概念的に既存のアイテムを上に移動します)。インデックス) とその逆。

代替手段は一貫した conj ですが、最悪の場合の複雑さははるかに悪くなります。

(パフォーマンス保証の表については、http://www.innoq.com/blog/st/2010/04/clojure_performance_guarantees.htmlを参照してください)

于 2013-06-25T08:04:01.353 に答える
3

表面的には、これがいかに奇妙に見えるかは理解できますが、conj がデフォルトの最も単純な「このコレクションに要素を追加する」アクションを実行するという考え方だと思います。ベクトルとリストは異なる方法で作成され、異なる種類のデフォルト アクションが必要です。

于 2013-06-25T13:02:11.643 に答える