コンピュテーション式といえばネットで拾った MaybeBuilder を訳も分からずコピペして使っているだけというレベルの私が、初めて自分でコンピュテーション式を作ってみました。何やら動いたけども、これで合ってるのか、もっといい方法があるのか、大変不安な状態なので恥を忍んでここにコードを晒してみます。もし添削して頂ける優しい方がいらっしゃるならば、何卒よろしくお願いいたします><
仕事柄、計算時間がかかる処理を作ることがちょくちょくあります。といっても何時間も計算機をぶん回すような計算はあまりなくて、数秒から数十秒程度の計算が殆ど、長くても数分でしょうか。この程度の計算時間でも計算処理の進捗状況が可視化されないとユーザーはイライラを感じますから、プログレスバーで大まかな進捗状況を可視化する必要が出てきます。
しかし当然ながら計算アルゴリズムを ProgressBar のような GUI 部品に依存させる設計は出来ませんから、処理の進捗を通知する部分をGUIから切り離す必要があります。今までは計算処理APIの引数にコールバック(のようなもの)を渡して進捗の通知を行ったりしていました。これをコンピュテーション式を使ってもっとカッコよく書きたい、というのが今回やりたいことです。
もう一つクリアしたい課題があります。とある計算処理Aは、それを単独で使用されることもあれば、別の計算処理Bの中で呼ばれることもあります。Aを単独で使用する場合はAの呼び出し終了時に進捗は100%で良いですが、処理Bから処理Aを呼び出している場合にはAだけで進捗を100%とするわけにはいきません。処理Bにおいて処理Aが占める割合を重み付けして進捗を通知する必要があります。こういう通知処理を書いていると割とコードが汚れてきて本来のアルゴリズムの見通しが悪くなるので、これをコンピュテーション式で改善できないのだろうか、と思っています。
(コンピュテーション式に拘っている訳ではなくて上記の問題を解決することが目的なので、別の解決方法があればそれでもOKです)
- 非同期関数が Async<'a> を返すように、進捗通知機能付き関数は Progressive<'a> を返すようにしたい。
- コンピュテーション式の中では let! で中身が取り出せて、進捗通知はあまり意識しなくても良いようにしたい。