F#での非同期ワークフローの例として、複数のWebページを並行して取得する例があります。その一例がで与えられます。将来的には、リンクの変更の場合には、ここで示したhttp://en.wikibooks.org/wiki/F_Sharp_Programming/Async_Workflowsコード:F#のグローバル状態と非同期ワークフロー
open System.Text.RegularExpressions
open System.Net
let download url =
let webclient = new System.Net.WebClient()
webclient.DownloadString(url : string)
let extractLinks html = Regex.Matches(html, @"http://\S+")
let downloadAndExtractLinks url =
let links = (url |> download |> extractLinks)
url, links.Count
let urls =
[@"http://www.craigslist.com/";
@"http://www.msn.com/";
@"http://en.wikibooks.org/wiki/Main_Page";
@"http://www.wordpress.com/";
@"http://news.google.com/";]
let pmap f l =
seq { for a in l -> async { return f a } }
|> Async.Parallel
|> Async.Run
let testSynchronous() = List.map downloadAndExtractLinks urls
let testAsynchronous() = pmap downloadAndExtractLinks urls
let time msg f =
let stopwatch = System.Diagnostics.Stopwatch.StartNew()
let temp = f()
stopwatch.Stop()
printfn "(%f ms) %s: %A" stopwatch.Elapsed.TotalMilliseconds msg temp
let main() =
printfn "Start..."
time "Synchronous" testSynchronous
time "Asynchronous" testAsynchronous
printfn "Done."
main()
私が知りたいのですが何が1は、このようなネットワーク接続の喪失などのグローバルな状態の変化を処理する方法ですか?これを行うエレガントな方法はありますか?
Async.Parallelコールを行う前にネットワークの状態をチェックできますが、実行中に状態が変わる可能性があります。ネットワークが失敗するのではなく、ネットワークが再び利用可能になるまで、実行を一時停止することを想定していたと仮定すると、これを行うための機能的な方法はありますか?
Tom、私はF#エージェントが本当に好きですが、これはHaskellのような関数型プログラミングではありません。それは、状態(ハスケルのIO Monad)を関数に渡すものとして扱うことであり、状態を複数のエージェントによって「同時に」変更され、エージェント間のメッセージ受け渡しで仲裁されるものとして扱います。 – JonnyBoats
エージェントの使用は間違いなくHaskellのような関数型プログラミングではありません。私は正直なところ、問題の純粋に機能的な解決策は、それがエレガントで便利だとは思わない。メッセージを渡す並行性は、F#で利用できるもう1つの有用なパラダイムです。そして、私は、それを調整する必要のある並行プロセスではうまく機能すると思います。 –
これは私が現時点で頭を上げようとしていることです。 Haskellのようなものを通してFPを発見したが(それでも未熟ではあるが)、F#でも完全に純粋なアプローチをとることが誘惑である。パラダイムの正しいブレンドを見つけることは、長い学習プロセスになると私は思う。 – shambulator