F#组成模式匹配函数

时间:2012-02-22 16:35:40

标签: f# composition

我有以下类型:

  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'。”

1 个答案:

答案 0 :(得分:3)

我可以在compose函数中看到两个问题。

分解p1p2时,模式需要包含在括号中(否则,编译器会将代码解释为RetryPolicy 函数的定义 ,而不是模式匹配):

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

稍后调用fn'时,你需要在元组中传递参数(否则,编译器会认为你只用一个参数调用fn' c然后建立一个元组):

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

我没有检查(或试图运行)整个示例,因此我不知道代码的其余部分是否符合您的要求。