2012-02-22 10 views
1

私は、これらのタイプがあります。F#のコンパターンマッチ機能

type ShouldRetry = ShouldRetry of (RetryCount * LastException -> bool * RetryDelay) 
    and RetryCount = int 
    and LastException = exn 
    and RetryDelay = TimeSpan 

    type RetryPolicy = RetryPolicy of ShouldRetry 

は、今私は、再試行の構成可能性をしたいです。このような何か:

let serverOverloaded = [| exnRetry<TimeoutException>; 
          exnRetry<ServerBusyException> |] 
         |> Array.map (fun fn -> fn (TimeSpan.FromSeconds(4.0))) 

let badNetwork = [||] // etc 

let compose p1 p2 = 
    // http://fssnip.net/7h 
    RetryPolicy(ShouldRetry((fun (c,e) -> 
    let RetryPolicy(ShouldRetry(fn)) = p1 
    let RetryPolicy(ShouldRetry(fn')) = p2 
    let (cont, delay) = fn c,e 
    if cont then cont, delay 
    else 
     let (cont', delay') = fn' c,e 
     cont', delay'))) 

let finalPolicy = serverOverloaded |> Array.scan compose (RetryPolicies.NoRetry()) 

しかし、私は、「値またはコンストラクタ 『FN』が定義されていません」と言って、fndelayfn'にコンパイルエラーを取得しています。

答えて

3

composeの機能に2つの問題があります。

p1p2を分解するとき、パターンは括弧内にラップされる必要がある(そうでない場合、コンパイラはなくパターンマッチング、RetryPolicy機能の定義としてコードを解釈):

let (RetryPolicy(ShouldRetry(fn))) = p1 
let (RetryPolicy(ShouldRetry(fn'))) = p2 

発呼fn'少し後で、引数にタプルを渡す必要があります(そうでなければ、コンパイラはfn'を引数1つだけでcと呼んでタプルを作成すると考えています):

let (cont', delay') = fn' (c,e) 

例全体をチェックしなかった(または実行しようとした)ので、コードの残りの部分が必要な場合にはわかりません。

関連する問題