申し訳ありませんが、この問題の説明は非常に抽象的です。それは私の仕事のためであり、商業上の機密保持上の理由から、現実世界の問題を示すことはできず、単なる抽象化です。
キーと値のペアを含むメッセージを受信するアプリケーションがあります。キーは定義済みの一連のキーワードから取得され、各キーワードには固定のデータ型があります。したがって、「Foo」が整数で「Bar」が日付の場合、次のようなメッセージが表示される可能性があります。
Foo: 234
Bar: 24 September 2011
メッセージには、キーの任意のサブセットが含まれる場合があります。キーの数はかなり多い(数十個)。しかし、今のところ Foo と Bar に固執しましょう。
明らかに、メッセージに対応する次のようなレコードがあります。
data MyRecord {
foo :: Maybe Integer
bar :: Maybe UTCTime
-- ... and so on for several dozen fields.
}
そのフィールドはまだ受信されていない可能性があるため、レコードは「Maybe」タイプを使用します。
現在の値から計算する必要がある多くの派生値もあります (存在する場合)。たとえば、私はしたいです
baz :: MyRecord -> Maybe String
baz r = do -- Maybe monad
f <- foo r
b <- bar r
return $ show f ++ " " ++ show b
これらの関数のいくつかは遅いので、不必要に繰り返したくありません。新しいメッセージごとに baz を再計算し、元の構造にメモすることもできますが、メッセージが foo フィールドと bar フィールドを変更しないままにしておくと、CPU 時間が無駄になります。逆に、必要なときにいつでも baz を再計算できますが、基礎となる引数が前回から変更されていない場合は、CPU 時間が無駄になります。
私が欲しいのは、引数が変更されたときにのみ baz を再計算する、ある種のスマートなメモ化またはプッシュベースの再計算です。baz は foo と bar のみに依存しているため、これらの値を変更するメッセージでのみ再計算することに注意することで、これを手動で検出できますが、エラーが発生しやすい複雑な関数の場合です。
追加の問題は、これらの関数の一部が複数の戦略を持つ可能性があることです。たとえば、「mplus」を使用して Foo または Bar から計算できる値があるとします。
これに対する既存の解決策を知っている人はいますか?そうでない場合、どうすればいいですか?