Math F#理解递归函数

Math F#理解递归函数,math,recursion,f#,Math,Recursion,F#,我试图理解为什么递归函数的行为是这样的 let rec fact = function |0 -> 1 |n -> n * fact(n-1);; 当我执行: fact 4;; 它答复说: val it : int = 24 这当然是正确的,因为1*2*3*4=24 我不明白的是这段代码: |n -> n * fact(n-1);; 我不明白为什么它不计算: 4 -> 4 * (4-1) 4 -> 4 * 3 4 -> 12 我猜我误解

我试图理解为什么递归函数的行为是这样的

let rec fact = function 
   |0 -> 1
   |n -> n * fact(n-1);;
当我执行:

fact 4;;
它答复说:

val it : int = 24
这当然是正确的,因为1*2*3*4=24

我不明白的是这段代码:

|n -> n * fact(n-1);;
我不明白为什么它不计算:

4 -> 4 * (4-1)
4 -> 4 * 3
4 -> 12
我猜我误解了n的定义


有人能做这件事来启发我吗

它不是在计算
4*(4-1)
,因为代码不是
n*(n-1)
。它是
n*事实(n-1)
,因此它计算
4*事实(4-1)
,即:

  4 * fact (4 - 1)
= 4 * fact 3
= 4 * (function | 0 -> 1 | n -> n * fact (n-1)) 3
= 4 * (match 3 with | 0 -> 1 | n -> n * fact (n-1))
= 4 * 3 * fact (3 - 1)
= 4 * 3 * fact 2
...

依此类推,直到你最终得到
4*3*2*1*fact 0=4*3*2*1*1=24
,如果定义是
n->n*(n-1)
,那么这将是正确的,但它是对
fact
的递归调用,因此:

4 * fact(4 - 1)
=> 4 * fact(3)
=> 4 * (3 * fact(2))
=> 4 * (3 * (2 * fact(1)))
=> 4 * (3 * (2 * (1 * fact(0))))
=> 4 * (3 * (2 * (1 * 1)))
=> 4 * (3 * (2 * 1))
=> 4 * (3 * 2)
=> 4 * 6
=> 24
我想我现在明白了

fact 4;; 
fun 4 match 4 with |0 -> 1|n -> n * fact(n-1)
|0 -> 1|4 -> 4 * fact(4-1)
|false |4 -> 4 * fact(3)
|false |4 -> 4 * fun 3 match 3 with |0 -> 1|n -> n * fact(n-1)
|false |4 -> 4 * |0 -> 1|3 -> 3 * fact(3-1)
|false |4 -> 4 * |false |3 -> 3 * fact(2)
|false |4 -> 4 * |false |3 -> 3 * fun 2 match 2 with |0 -> 1|n -> n * fact(n-1)
|false |4 -> 4 * |false |3 -> 3 * |0 -> 1|2 -> 2 * fact(2-1)
|false |4 -> 4 * |false |3 -> 3 * |false |2 -> 2 * fact(1)
|false |4 -> 4 * |false |3 -> 3 * |false |2 -> 2 * fun 1 match 1 with |0 -> 1|n -> n * fact(n-1)
|false |4 -> 4 * |false |3 -> 3 * |false |2 -> 2 * |0 -> 1|1 -> 1 * fact(1-1)
|false |4 -> 4 * |false |3 -> 3 * |false |2 -> 2 * |false |1 -> 1 * fact(0)
|false |4 -> 4 * |false |3 -> 3 * |false |2 -> 2 * |false |1 -> 1 * fun 0 match 0 with |0 -> 1|n -> n * fact(n-1)
|false |4 -> 4 * |false |3 -> 3 * |false |2 -> 2 * |false |1 -> 1 * |true|
4 -> 4 * 3 -> 3 * 2 -> 2 * 1 -> 1 * 0 -> 1 = 24 

我认为rec是使我的函数递归的原因,那么为什么当我从代码中删除rec时,我仍然得到相同的结果呢?顺便说一句,你说的每句话都有道理。@Nulle-正是从
fact
函数中调用
fact
使其递归。F#要求使用
rec
声明递归函数,以使函数名在声明函数中可见。如果您只是删除
rec
关键字,您应该会得到一个编译错误,说明没有定义
fact
@Nulle
rec
是允许您的函数递归的。如果你删除它,你应该会得到一个错误,除非之前有一个
事实的定义。
。我很难弄清楚在你说“匹配3…”时发生了什么。你能详细说明一下吗?@Nulle
函数| 0->1 | n->n*事实(n-1)
是编写
funx->matchx和| 0->1 | n->n*事实(n-1)
的快捷方式。如果我们将该函数应用于参数
3
,我们将得到
匹配3与| 0->1 | n->n*事实(n-1)