2012-02-22 98 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()) 

但是我卻越來越對fndelayfn'編譯器錯誤,稱「值或構造‘FN’沒有定義」。

回答

3

我可以在compose函數中看到兩個問題。

當分解p1p2,圖案需要被包裹在括號(否則,編譯器解釋的,而不是圖案匹配的代碼的RetryPolicy功能一個定義,):

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

致電時fn'稍後,您需要將它傳遞給元組中的參數(否則,編譯器認爲您只用一個參數c調用fn',然後構建元組):

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

我沒有檢查(或試圖運行)整個例子,所以我不知道其餘的代碼是否做你想要的。