F #: не понимая совпадения .. с

Я возиться с F # и Fable, и пытаюсь проверить мое понимание. Для этого я попытался создать функцию для вычисления e с учетом определенного числа итераций. Что я придумал, так это

let eCalc n =
      let rec internalECalc ifact sum count =
          match count = n with
          | true -> sum
          | _ -> internalECalc (ifact / (float count)) (sum + ifact) (count+1)

      internalECalc 1.0 0.0 1

Который работает нормально, возвращая 2.7182818284590455 при вызове с

eCalc 20

Однако, если я попытаюсь использовать, как мне кажется, более правильную форму

let eCalc n =
      let rec internalECalc ifact sum count =
          match count with
          | n -> sum
          | _ -> internalECalc (ifact / (float count)) (sum + ifact) (count+1)

      internalECalc 1.0 0.0 1

Я получаю предупреждение «[ПРЕДУПРЕЖДЕНИЕ] Это правило никогда не будет совпадать (L5,10-L5,11)» и возвращает значение 0. (То же самое происходит, если я поменяю местами «n» и «count» в матче заявление). Есть ли причина, по которой я не могу использовать 'n' в выражении соответствия? Есть ли способ обойти это, чтобы я мог использовать 'n'?

Спасибо

Ответы на вопрос(1)

Решение Вопроса

Когда вы используете имя вmatch Скажите, выне сверяя его со значением, присвоенным этой переменной, таким, каким вы себя считаете. Вы вместоназначение это имя. т.е.,

match someInt with
| n -> printfn "%d" n

напечатает значениеsomeInt, Это эквивалентlet n = someInt; printfn "%d" n.

То, что вы хотели сделать, это использоватьwhen оговорка; внутриwhen пункт, вы не сопоставление с образцом, но делаете "стандартную", если проверка. Итак, что вы хотели:

let eCalc n =
      let rec internalECalc ifact sum count =
          match count with
          | cnt when cnt = n -> sum
          | _ -> internalECalc (ifact / (float count)) (sum + ifact) (count+1)

      internalECalc 1.0 0.0 1

Это имеет смысл, или вам нужно, чтобы я углубился в детали?

Постскриптум В случае, подобном этому, где ваша функция соответствия выглядит как «x when (логическое условие, включающее x) -> case 1 | _ -> case 2», гораздо проще читать простойif выражение:

let eCalc n =
      let rec internalECalc ifact sum count =
          if count = n then
              sum
          else
              internalECalc (ifact / (float count)) (sum + ifact) (count+1)

      internalECalc 1.0 0.0 1
 Mark Seemann02 авг. 2016 г., 07:21
Это хорошее объяснение, так что просим за это :) Я думаю, что более простым и идиоматичным решением, однако, было бы использованиеif/then/else выражение.
 rmunn02 авг. 2016 г., 07:26
Да,if/then/else лучше в этом случае. Я хотел остаться как можно ближе к исходному коду ОП, чтобы проиллюстрировать разницу, но я мог бы также отредактировать ответ, чтобы показать лучший путь.
 JRogerC02 авг. 2016 г., 15:26
Это было очень полезно. В моем исходном коде использовался оператор if / then, но я хотел что-то, что выглядело бы «красиво», или Haskellish (это был мой первый функциональный язык).
 Mark Seemann02 авг. 2016 г., 07:30
Я думаю, что это хорошо, чтобы показать синтаксис соответствия шаблону, как вы сделали, поэтому я бы оставил его в ответе, но тогда, возможно, такжедобавлять if/then/else вариант.

Ваш ответ на вопрос