F#:不理解匹配..用

JRo*_*erC 2 f#

我正在搞乱F#和Fable,并试图测试我的理解.为此,我尝试创建一个函数来计算给定一定次数的迭代次数.我想出的是

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
Run Code Online (Sandbox Code Playgroud)

哪个工作正常,调用后返回2.7182818284590455

eCalc 20
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试使用,我认为是更正确的形式

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
Run Code Online (Sandbox Code Playgroud)

我收到警告"[警告]此规则永远不会匹配(L5,10-L5,11)",返回值为0.(如果我在匹配中交换'n'和'count',也会发生同样的事情声明).有没有理由我不能在比赛声明中使用'n'?有没有办法解决这个问题,所以我可以使用'n'?

谢谢

rmu*_*unn 10

当您在match语句中使用名称时,您不会按照您认为的方式对照分配给该变量的值进行检查.而是分配该名称.也就是说,

match someInt with
| n -> printfn "%d" n
Run Code Online (Sandbox Code Playgroud)

将打印的值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
Run Code Online (Sandbox Code Playgroud)

这是否有意义,或者您是否需要我详细介绍?

PS在像这样的情况下,你的匹配函数看起来像"x when(布尔条件涉及x) - >案例1 | _ - >案例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
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的解释,所以为此投票:)我认为更简单,更惯用的解决方案是使用`if/then/else`表达式. (4认同)