ここで私の問題を解決するのに役立つ多くの投稿を読みましたが、私の試みはすべて実を結びませんでした.
私のコードを聞いてください:
最初の機能 (使用するファイルを 1 行ずつ読み込む)
let readLines filePath = System.IO.File.ReadLines(filePath)
2 番目の関数 (行の処理) 編集: タイプミス エラー 最初の投稿で文字列行を忘れました
let processLine (line:string) (myobj:MYOBJ) =
// .... some processing
myobj // I return the object modified
今、私はこれでファイルを非同期的に処理したいと思います(試みは機能していません!しかし、目的は私が何をしたいのかを説明することです)
let processAll file =
async { // some processing
let mutable obj = new MYOBJ()
readLines file
|> Seq.iter (fun l -> let obj = proceesLine l ) // I would like to modify the object after each Line
}
ref と ! を使ってみた ミューテーションを処理することはできましたが、クリーンで明確な解決策は思いつきませんでした。この場合、どのようなコード プラクティスが最適でしょうか?
考えられる解決策: 貴重なご協力に感謝します。考えられる解決策は 2 つあります。
最初の解決策:
let readL (file:string) =
async {
let mutable myobj = ref(new MYOBJ())
use sr = new StreamReader(file)
while not sr.EndOfStream do
let line = sr.ReadLine()
myobj := proccesLine line !myobj
()
sr.Close()
}
2番目の解決策:(CSVReaderライブラリを使用)
let readL (file:string) =
async {
let myobj = new MYOBJ()
use sr = new CsvReader(new StreamReader(file),false)
let fcount = sr.FieldCount
let data : string array = Array.zeroCreate fcount
let rec readLinloop (readNext, str:CsvReader, obj:MYOBJ) =
match readNext with
| false -> ()
| true -> sr.CopyCurrentRecordPartTo(data,0)
let obj = processLine data obj
readL(str.ReadNextRecord(), str, obj)
readLinLoop(sr.ReadNextRecord(),sr, myobj)
sr.Dispose()
}
ここで、Seq.iter を使用しているときに、ユニット型以外を返すインライン関数を使用できるかどうかを知りたいと思いました。コードははるかに読みやすくなります。
編集:問題を解決したiljarnによって提案された3番目のソリューション
let processAll file =
async { (MYOBJ(), readLines file) ||> Seq.fold processLine }