関数型コードは非関数型コードよりも本質的に並列化が容易であると常に耳にするので、次のことを行う関数を作成することにしました。
文字列の入力が与えられた場合、各文字列の一意の文字の数を合計します。したがって、入力が与えられると[ "aaaaa"; "bbb"; "ccccccc"; "abbbc" ]
、メソッドはを返しますa: 6; b: 6; c: 8
。
これが私が書いたものです:
(* seq<#seq<char>> -> Map<char,int> *)
let wordFrequency input =
input
|> Seq.fold (fun acc text ->
(* This inner loop can be processed on its own thread *)
text
|> Seq.choose (fun char -> if Char.IsLetter char then Some(char) else None)
|> Seq.fold (fun (acc : Map<_,_>) item ->
match acc.TryFind(item) with
| Some(count) -> acc.Add(item, count + 1)
| None -> acc.Add(item, 1))
acc
) Map.empty
input
の各文字列は独自のスレッドで処理できるため、このコードは理想的には並列化可能です。インナーループはすべての入力間で共有されるマップにアイテムを追加するため、見た目ほど簡単ではありません。
内側のループを独自のスレッドに分解したいのですが、可変状態を使用したくありません。非同期ワークフローを使用してこの関数を書き直すにはどうすればよいですか?