0

我在这里阅读了很多帖子,这些帖子对我的问题有很大帮助,但我所有的尝试都没有结果。

听到是我的代码:

第一个函数(逐行读取文件以供使用)

let readLines filePath = System.IO.File.ReadLines(filePath)

第二个函数(处理行)编辑:错字错误我在第一篇文章中忘记了字符串行

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 和!处理突变,但没有想出一个干净清晰的解决方案。在这种情况下,最佳代码实践是什么?

可能的解决方案:感谢您的宝贵帮助,这里有两种可能的解决方案

第一种解决方案:

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()
        }

第二个解决方案:(使用 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 提出的解决问题的第三个解决方案

let processAll file =
    async { (MYOBJ(), readLines file) ||> Seq.fold processLine }
4

1 回答 1

2

这似乎是一个合适的用例Seq.fold

let processAll file =
    async { (MYOBJ(), readLines file) ||> Seq.fold (fun o l -> processLine l o) }

请注意,如果您颠倒processLine's 参数的顺序,则可以将其简化为:

let processAll file =
    async { (MYOBJ(), readLines file) ||> Seq.fold processLine }
于 2013-04-04T16:51:33.247 回答