F#从单个方法管理多个延迟序列?

时间:2010-10-28 06:14:04

标签: f# sequences

我试图找出如何从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

2 个答案:

答案 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 
[||] 

无效。也许你希望你的函数返回两个序列的元组?或者在遇到错误时使用某种可变集合来编写错误?