「通常のハッシュテーブルと同じくらいスペース効率が良い」というのはかなりあいまいな仕様です。わかりやすい永続ハッシュ テーブルを設計した人はまだいないと思います。
必要な複雑さを持つ永続的なキー値マップを取得する最も簡単な方法は、永続的な二分探索ツリーを使用することです。ルックアップは、一時的な (非永続的な) BST でおなじみのアルゴリズムです。ただし、変更を挿入すると、(疑似 Java) のようになります。
// overwrites the value for k if it's already in the tree
Node insert(Node node, Key k, Value v)
{
if (k < node.key)
return new Node(node.key, node.val, insert(node.left, k, v), node.right);
else if (k > node.key)
return new Node(node.key, node.val, node.left, insert(node.right, k, v));
else
return new Node(k, v, node.left, node.right);
}
挿入ルーチンは新しいツリーを返すことに注意してください。これは非効率に見えるかもしれませんが、トラバースするノードのみを変更します。これは平均で O(lg n ) なので、平均で O(lg n ) 回の割り当てを行います。これは、得られるスペース効率とほぼ同じです。
最悪の場合の O(lg n ) の動作を取得するには、赤黒木を使用します。関数型プログラミングのデータ構造に関する文献も参照してください。