F # составить шаблон совпавшей функции - PullRequest
1 голос
/ 22 февраля 2012

У меня есть эти типы:

  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' не определены".

1 Ответ

3 голосов
/ 22 февраля 2012

Я вижу две проблемы в вашей функции compose.

При разложении p1 и p2 шаблон должен быть заключен в скобки (в противном случае компилятор интерпретирует код как определениеиз RetryPolicy функция вместо сопоставления с образцом):

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

При вызове fn' чуть позже, вам нужно передать ему аргументы в кортеже (в противном случае,компилятор считает, что вы вызываете fn' с одним аргументом c, а затем создаете кортеж):

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

Я не проверял (или пытался запустить) весь пример, поэтомуЯ не знаю, выполняет ли оставшаяся часть кода то, что вы хотите.

...