何百万ものエントリを含む大きなハッシュマップがあり、それをディスクに保存して、ディスクから再度読み取るときに、キーと値のペアをマップに再度挿入するオーバーヘッドがないようにしたいと考えています。
これを行うために穀物ライブラリを使用しようとしていますが、HashMapデータ型は Generic を派生させる必要があるようです。これを行う方法はありますか?
何百万ものエントリを含む大きなハッシュマップがあり、それをディスクに保存して、ディスクから再度読み取るときに、キーと値のペアをマップに再度挿入するオーバーヘッドがないようにしたいと考えています。
これを行うために穀物ライブラリを使用しようとしていますが、HashMapデータ型は Generic を派生させる必要があるようです。これを行う方法はありますか?
スタンドアロンの派生を使用して、 の独自のGeneric
インスタンスを生成できる場合がありHashMap
ます。おそらく孤立したインスタンスに関する警告が表示されますが、おそらく気にしないでしょう:)とにかく、私はこれを試していませんが、おそらく試してみる価値があります...
Generics を使用することが、高いパフォーマンスを達成するための最良の方法であるかどうかはわかりません。私の最善の策は、実際には次のように Serializable の独自のインスタンスを作成することです。
instance (Serializable a) => Serializable (HashMap a) where
...
孤立したインスタンスの作成を回避するには、newtype トリックを使用できます。
newtype SerializableHashMap a = SerializableHashMap { toHashMap :: HashMap a }
instance (Serializable a) => SerializableHashMap a where
...
...
問題は、どのように?を定義するかです。
可能なソリューションを実際に試して実装し、ベンチマークする前に、明確な答えはありません。
toList
考えられる解決策の 1 つは、 /fromList
関数を使用して、 HashMap
.
もう 1 つは (Generics の使用に似ています)、内部の HashMap 構造に基づいて直接シリアル化を作成することです。ジェネリックのみの仕事になる内部を実際にエクスポートしていないという事実を考えると。
現在、HashMap ライブラリ自体を変更せずに HashMap をシリアライズ可能にする方法はありません。
Data.HashMap はすべてのコンストラクターをエクスポートしないため (これは GHC の要件です)、@mergeconflict の回答で説明されているように、スタンドアロンの派生を使用して Data.HashMap を Generic のインスタンス (シリアルで使用するため) にすることはできません。
したがって、HashMap をシリアル化するために残された唯一の解決策は、toList/fromList インターフェイスを使用することのようです。
CerealPlus パッケージは、厳密な HashMap の Serialize の定義を提供します。