Реализация конструкторов рабочих процессов F #: обработка исключений в конструкциях for..in..do - PullRequest
3 голосов
/ 06 декабря 2010

Продолжая исследовать компоновщики рабочих процессов F #, я решил поэкспериментировать с обработкой исключений в компоновщике, в частности с конструкцией for..in..do.

Конечной целью этого эксперимента является построитель рабочего процесса, который продолжит обработку последовательности даже при возникновении исключения.

Нижеприведенное, например, не работает, потому что метод For построителя, по-видимому, не вызывается до точки, где происходит исключение (при первом вызове Directory.EnumerateFiles (dir))

type failSafeSeq() =
    member this.For(seq1, mapFunction) =
        try
            seq1 |> Seq.collect mapFunction
        with
            ex -> Console.WriteLine ex
                  Seq.empty
    member this.Yield(yieldExpr) = yieldExpr |> Seq.singleton
    member this.YieldFrom(yieldBang) = yieldBang
    member this.Combine(a, b) = Seq.append a b
    member this.Delay(delayFun) = delayFun()
    member this.Zero() = Seq.empty 

let failSafe = new failSafeSeq();

let rec allFilesSeq dir =
    failSafe { for file in Directory.EnumerateFiles(dir) do yield file
               for subdir in Directory.EnumerateDirectories dir do yield! (allFilesSeq subdir) }

[<EntryPoint>]
let main args =
    allFilesSeq "C:\\System Volume Information\\" //almost guaranteed to cause an UnauthorizedAccessException on Windows systems at the first Directory.EnumerateFiles(dir) call.
    |> Seq.iter Console.WriteLine
    0

Возможно ли это с использованием рабочих процессов F #?

1 Ответ

1 голос
/ 06 декабря 2010

Нет;согласно spec для выражений вычислений,

... for pat in expr do cexpr ...

переводится в

... b.For(expr, fun pat -> cexpr) ...

, что означает, что expr вычисляется до For, и еслион бросает, тогда, конечно, For не вызывается.

Кстати, ваша стратегия также не будет работать как есть, поскольку seq s ленивы, и, например, Seq.collect обычно не бросает (скореекод, который вызывает его и оценивает последовательность, может вызвать запуск кода, который выдает).

Существует ряд других способов реализации чего-либо по принципу «восстановления seq s» ...Я думаю, что рабочий процесс, возможно, является неправильным подходом, и вместо этого вам просто нужно несколько оберточных комбинаторов для seq создания и отображения.

Какова реальная конечная цель?Это «выздоровление seq» не кажется мне полезным, как вы собираетесь его применить?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...