と CCRを使用する F# エージェントMailboxProcessor
は異なるプログラミング モデルを実装していると思いますが、どちらも同じように強力であると信じています。メールボックスを中心に構築された F#。CCR に基づくプログラミング モデルは、 COmega (古い MSR プロジェクト)などの結合計算に基づくさまざまな言語で、おそらくより明確に記述されています。
たとえば、COmega エージェントと F# エージェントを使用して、1 プレース バッファーの実装を比較できます。
public class OnePlaceBuffer {
private async empty();
private async contains(string s);
public OnePlaceBuffer() { empty(); }
public void Put(string s) & empty() {
contains(s);
}
public string Get() & contains(string s) {
empty();
return s;
}
}
empty
この例では、非同期メソッドはメールボックスのように動作し (つまり、 、contains
、Put
およびの 4 つがありますGet
)、ボディはハンドラーのように動作し、メールボックスの組み合わせに値が含まれている場合 (つまり、空のバッファーに入れたり、フルバッファから取得したとき)。F# では、次のように使用および記述できます。MailboxProcessor
type Message<'T> =
| Put of 'T * AsyncReplyChannel<unit>
| Get of AsyncReplyChannel<'T>
MailboxProcessor.Start(fun agent ->
let rec empty = agent.Scan(function
| Put(v, repl) -> repl.Reply(); Some(full(v))
| _ -> None)
and full v = agent.Scan(function
| Get repl -> repl.Reply(v); Some(empty)
| _ -> None)
empty )
2 つの実装は同じ考え方を表現していますが、少し異なる方法で表現されています。F# では、empty
とfull
はエージェントのさまざまな状態を表す 2 つの関数であり、エージェントに送信されるメッセージは、エージェントの状態 (保留中の作業) のさまざまな側面を表します。COmega の実装では、プログラムのすべての状態がメールボックスによってキャプチャされます。
MailboxProcessor
エージェントの状態を、処理が必要な直接のメッセージから分離することで、F# について考えるのが少し簡単になるかもしれないと思いますが、それは根拠のないただの考えです...
最後に、MailboxProcessor
F# で使用する現実的なアプリケーションでは、より多くの数を使用する可能性が非常に高く、それらは何らかの方法で接続されます。たとえば、パイプライン処理の実装は、複数のMailboxProcessor
インスタンスを使用するアプリケーションの良い例です (もちろん、すべてのインスタンスには単純な実行中の非同期ワークフローが関連付けられています)。例については、この記事を参照してください。