2010-12-05 9 views
3

F#ワークフロービルダを引き続き調査する際に、ビルダーでの例外処理、特に "for..in..do "構築する。F#ワークフロービルダの実装:for..in..doコンストラクトの例外処理

この実験の最終目標は、例外が発生してもシーケンスを処理し続けるワークフロービルダーです。

ビルダーの方法については例外が

(最初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

いいえ;

exprFor前に評価されることを意味し、それがスローした場合、その後の進路Forが呼び出されない

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

に変換され、計算式のspecあたりとして。

seqは遅延しているため、戦略はそのままでは機能しません。 Seq.collectは通常はスローされません(むしろ、それを呼び出すコードでシーケンスを評価すると、スローするコードが実行される可能性があります)。

あなたは「seqのを回復」の線に沿って何かを実装することができ、他のいくつかの方法があります...私は、ワークフローは、おそらく間違ったアプローチであると思うし、代わりにあなただけのseq作成とマッピングのためのいくつかのラッピングコンビネータをしたいです。

実際の最終目標は何ですか?この 'recovering seq'は私には役に立たないようですが、どのように適用するつもりですか?

+0

この時点で、私はF#を言語として探求しようとしていて、私にとって馴染みのない概念に精通しています。この場合、私はF#ワークフローの境界と機能を探求しようとしています。ちなみに、私はこの例を、「Maybe」モナド/ワークフローの準正反対として、http://leibnizdream.wordpress.com/2008/10/21/why-use-computation-workflows-aka-monadsを読んだ後に試してみることにしました-in-f /。私は後でもっと実用的なコーディングに移ります:)。答えをありがとう! – Nathan

+0

私は同じタイプが好きです。フォールトトレラントパイプライン。ソリューションの進捗状況 –