1

RacketやSMLのような関数型言語では、通常、再帰呼び出しでリスト操作を実行します(パターンマッチング、リスト追加、リスト連結...)。ただし、関数型言語でのこれらの操作の一般的な実装はわかりません。リスト内の要素の作成、更新、削除などの操作は、リストのまったく新しいコピーを返しますか?私はかつて、関数型プログラミングの欠点についての例を本で読んだことがあります。つまり、データベースが更新されるたびに、データベースのまったく新しいコピーが返されます。

FPのデータは本質的に不変であるため、この例に疑問を投げかけました。したがって、既存のリストからリストを作成しても、まったく新しいコピーが作成されることはありません。代わりに、新しいリストは、フィルタリング基準に基づいた、他のリスト内の既存のオブジェクトへの参照の単なる異なるコレクションです。

たとえば、list A = [a,b,c]、list B=[1,2,3]、および既存のリストの最初の2つの要素を含む新しいリストを作成しましたC=[a,b,1,2]。この新しいリストには、a,b,fromAおよび1,2fromへの参照が含まれているだけBです。データは不変であるため、新しいコピーであってはなりません。

したがって、リスト内の要素を更新するには、リスト内の要素を見つけ、新しい値を作成し、更新されたものを除いて古いリストと同じ要素で新しいリストを作成するのに、直線的な時間しかかかりません。新しいリストを作成するために、実行環境は前の要素の次のポインターを更新するだけです。リストが非アトミック要素(つまり、リスト、ツリー...)を保持していて、非アトミック要素の1つで1つのアトミック要素のみが更新される場合、このプロセスは、アトミック要素まで非アトミック要素に再帰的に適用されます。上記のように更新されます。これはどのように実装されるべきですか?

誰かが既存のリスト/追加/更新/削除/要素を使用してリストを作成するたびにリストの完全なコピーを作成する場合、彼らはそれを間違っていますね?

もう1つは、プログラム環境が更新されたとき(つまり、新しい変数に新しいキー/値エントリを追加して、後で参照できるようにする)、関数型プログラミングの不変のプロパティに違反しないということです。

4

1 に答える 1

2

あなたは絶対に正しいです!不変のデータを持つFP言語は、(実際に実装が不十分でない限り)ディープコピーを実行することはありません。データ不変であるため、再利用しても問題はありません。他のすべての構造とまったく同じように機能します。したがって、たとえば、ツリー構造で作業している場合、コピーされるのはせいぜい実際のツリーのみであり、それに含まれるデータはコピーされません。

したがって、コピーは非常に高価に聞こえますが、命令型/ OOバックグラウンド(可変データがあるため実際にコピーする必要がある場合)から来た場合に最初に考えるよりもはるかに安価です。そして、不変のデータを持つことには多くの利点があります。

于 2013-03-23T19:29:00.793 に答える