我有以下类型:
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
,delay
和fn'
上遇到编译器错误,说“未定义值或构造函数'fn'。”
答案 0 :(得分:3)
我可以在compose
函数中看到两个问题。
分解p1
和p2
时,模式需要包含在括号中(否则,编译器会将代码解释为RetryPolicy
函数的定义 ,而不是模式匹配):
let (RetryPolicy(ShouldRetry(fn))) = p1
let (RetryPolicy(ShouldRetry(fn'))) = p2
稍后调用fn'
时,你需要在元组中传递参数(否则,编译器会认为你只用一个参数调用fn'
c
然后建立一个元组):
let (cont', delay') = fn' (c,e)
我没有检查(或试图运行)整个示例,因此我不知道代码的其余部分是否符合您的要求。