我试图找出如何从F#中的单个函数管理多个延迟序列。
例如,在下面的代码中,我试图获得两个序列 - 一个返回目录中的所有文件,另一个返回任何无法访问的目录的元组序列(例如由于权限) )除了。
虽然下面的代码编译并运行,但是当其他代码使用时,errorSeq从不会有任何元素,即使我知道发生了UnauthorizedAccess异常。
我正在使用F#2.0。
#light
open System.IO
open System
let rec allFiles errorSeq dir =
Seq.append
(try
dir |> Directory.GetFiles
with
e -> Seq.append errorSeq [|(dir, e)|]
|> ignore
[||]
)
(try
dir
|> Directory.GetDirectories
|> Seq.map (allFiles errorSeq)
|> Seq.concat
with
e -> Seq.append errorSeq [|(dir, e)|]
|> ignore
Seq.empty
)
[<EntryPoint>]
let main args =
printfn "Arguments passed to function : %A" args
let errorSeq = Seq.empty
allFiles errorSeq args.[0]
|> Seq.filter (fun x -> (Path.GetExtension x).ToLowerInvariant() = ".jpg")
|> Seq.iter Console.WriteLine
errorSeq
|> Seq.iter (fun x ->
Console.WriteLine("Error")
x)
0
答案 0 :(得分:3)
如果你想采用更实用的方法,可以采用以下方法:
let rec allFiles (errorSeq, fileSeq) dir =
let files, errs =
try
Seq.append (dir |> Directory.GetFiles) fileSeq, errorSeq
with
e -> fileSeq, Seq.append [dir,e] errorSeq
let subdirs, errs =
try
dir |> Directory.GetDirectories, errs
with
e -> [||], Seq.append [dir,e] errs
Seq.fold allFiles (errs, files) subdirs
现在我们每次都将错误序列和文件序列传递给函数,并返回通过在函数中附加到它们而创建的新序列。我认为在这种情况下,必要的方法更容易理解。
答案 1 :(得分:2)
Seq.append
返回一个新序列,所以
Seq.append errorSeq [|(dir, e)|]
|> ignore
[||]
无效。也许你希望你的函数返回两个序列的元组?或者在遇到错误时使用某种可变集合来编写错误?