Haskellでグラフを作成してローカル操作を行う方法を学びたいのですが、問題はHaskellに固有のものではなく、グラフの代わりに二重リンクリストを検討することもできます。
質問: 主に不変のデータ構造(Haskell、Clojureなど)をサポートおよび推奨する言語で、二重リンクリスト(または他の二重リンクまたは循環データ構造)とその操作を実装する慣用的または推奨される方法は何ですか? ?特に、言語で正式に禁止されているインプレース更新の使用方法は?
二重にリンクされたリストでローカル操作を実行した場合(アイテムが挿入された場合など)、言語の遅延により、リスト全体をすぐにコピーする必要がない場合があることは容易に想像できます。ただし、リストは二重にリンクされているため、1か所で変更された場合、リストの新しいバージョンで古いノードを使用することはできず、何らかの方法でマーク、コピー、ガベージコレクションを行う必要があります。 。リストの更新されたコピーのみを使用する場合、これらは明らかに冗長な操作ですが、リストのサイズに比例した「オーバーヘッド」が追加されます。
これは、そのようなタスクでは不変データが単に不適切であり、可変データを「ネイティブ」でサポートしていない関数型宣言言語は、命令型言語ほど優れていないことを意味しますか?または、トリッキーな回避策はありますか?
PS私はインターネットでこの主題に関するいくつかの記事やプレゼンテーションを見つけましたが、それらをフォローするのに苦労しましたが、この質問への答えは1段落以上、そしておそらく図を取るべきではないと思います...つまり、もしあればこの問題に対する「機能的な」解決策はありません。答えは「Cを使用する」でしょう。ある場合、それはどれほど複雑になる可能性がありますか?
関連する質問
「関数型プログラミングのデータ構造」。非効率的な代替手段の代わりにインプレース更新を使用することについての私の特定の質問はそこでは議論されていません。
「永続的データ構造の内部変異」。ここでは、不特定の言語での低レベルの実装に重点が置かれているようですが、私の質問は、言語(関数型またはその他)の正しい選択と、関数型言語で可能な慣用的な解決策についてです。
関連する引用
純粋に関数型のプログラミング言語では、多くのアルゴリズムを非常に簡潔に表現できますが、その場で更新可能な状態が重要な役割を果たすと思われるアルゴリズムがいくつかあります。これらのアルゴリズムの場合、更新可能な状態がない純粋に関数型の言語は本質的に非効率的であるように見えます([Ponder、McGeer and Ng、1988])。
-John LaunchburyおよびSimon Peyton Jones、レイジー機能状態スレッド(1994)、John LaunchburyおよびSimon Peyton Jones、Haskell州(1995)。これらの論文ST
では、Haskellのモナディック型コンストラクタを紹介しています。
Map
、IntMap
またはHashMap
ストレージとして)とノードがリンクされたノードのIDを含めるようにします。 「コンピューターサイエンスのすべての問題は、別のレベルの間接参照で解決できます。」