评估期间堆栈溢出(循环递归?)。 OCaml的

时间:2012-09-19 21:49:52

标签: functional-programming ocaml

我正在尝试编写一个接受int n的函数,并返回一个从n到0的列表。

这就是我所拥有的

let rec downFrom n =
let m = n+1 in
if m = 0 then                                                                                  
  []                                                                                           
else                                                                                            
  (m-1) :: downFrom (m - 1);;

该函数编译好,但是当我用任何int测试它时它给了我错误 评估期间堆栈溢出(循环递归?)。

我知道这是当地的变种阻碍但我不知道另一种方式来宣布它。谢谢!!!

3 个答案:

答案 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]