我正在尝试编写一个接受int n的函数,并返回一个从n到0的列表。
这就是我所拥有的
let rec downFrom n =
let m = n+1 in
if m = 0 then
[]
else
(m-1) :: downFrom (m - 1);;
该函数编译好,但是当我用任何int测试它时它给了我错误 评估期间堆栈溢出(循环递归?)。
我知道这是当地的变种阻碍但我不知道另一种方式来宣布它。谢谢!!!
答案 0 :(得分:2)
首先,真正的错误的程序是你有一个无限循环。为什么,因为你的归纳基础案例是0,但你总是留在n
!这是因为您在真实m - 1
n + 1 - 1
上递归
我对此编译的原因感到惊讶,因为它不包含rec
关键字,这在递归函数中是必需的。为了避免OCaml中的堆栈溢出,通常会切换到tail recursive样式,如下所示:
let downFrom n =
let rec h n acc =
if n = 0 then List.rev acc else h (n-1) (n::acc)
in
h n []
有人建议进行以下编辑:
let downFrom n =
let rec h m acc =
if m > n then acc else h (m + 1) (m::acc)
in
h 0 [];
这保存了对List.rev的调用,我同意。
答案 1 :(得分:1)
递归的关键是递归调用必须是问题的较小版本。您的递归调用不会创建较小版本的问题。它只是重复同样的问题。
答案 2 :(得分:0)
您可以尝试使用过滤参数 语法:
let f = function
p1 -> expr1
| p2 -> expr2
| p3 -> ...;;
let rec n_to_one =function
0->[]
|n->n::n_to_one (n-1);;
# n_to_one 3;;
- : int list = [3; 2; 1]