Ocaml Stackoverflow

问题描述

为什么在某些功能中,当我使用诸如 List.filter它不返回错误:堆栈溢出

但是当我使用

let rec filter p l =
match l with
| [] -> []
| hd::tl -> if p hd then hd::(filter p l) else filter p l 

与List.filter具有相同的功能,它会产生堆栈溢出错误

解决方法

您的过滤器函数使用相同的列表l进行递归调用:

... then hd::(filter p l) else filter p l
             ^^^^^^^^^^^^      ^^^^^^^^^^

这意味着您永远不会收敛于解决方案,而是无限递归。

在小输入上到达堆栈溢出就是此类问题的征兆。 同样,在编写尾递归函数时,您可能会遇到非终止循环,这是识别程序何时不正确的另一种方法(某些程序是有目的的无限循环)。

在这种情况下,您需要使用tl(列表中的其余元素)。如果您希望函数终止,那么在递归的每个步骤中都要进行收缩是很重要的。